.. and by repeated, I mean repeated. I have a simple implementation of a list interface, functioning like a simple baby-version of the LinkedList.
I have the classes "Knoten"(means "knot" in German), MyLinkedList and, well, Main.
The Error my compiler tosses at me originates in class Knoten, line 35.
But it doesn´t tell me what kind of error it is.
"at Knoten.nextN(Knoten.java:35)"
is all it says. A million times. My whole cmd window is filled with this line. I bet it printed this error message for more than hundred times, again and again. I tried to search for similar problems, but couldn´t really find anything useful because I don´t know which error to search for.
Why did my program crash?
Please help..
Knoten:
class Knoten<T> {
Knoten nachfolger;
T t;
public Knoten(T t){
this.t = t;
nachfolger = null;
}
public void add(T tneu) {
if (nachfolger != null) {
nachfolger.add(tneu);
}
else {
Knoten kneu = new Knoten(tneu);
nachfolger = kneu;
}
}
public Knoten giveNachfolger(){
return nachfolger;
}
public T fuerIDGeben(int index, Knoten anfang) {
if(index == nextN(anfang)){
return (T) nachfolger.t;
}
return null;
}
private int nextN(Knoten k){
int i = 1;
if (nachfolger != null){
i = i+1;
nextN(nachfolger);
} else {}
return i;
} }
MyLinkedList:
class MyLinkedList<T> implements MyList<T>{
Knoten anfang;
public MyLinkedList<T>(){
anfang = null;
}
public T get(int index){
return (T) anfang.fuerIDGeben(index, anfang);
}
public void add(T t){
if(anfang != null){
anfang.add(t);
} else {
Knoten newKnoten = new Knoten(t);
anfang = newKnoten;
}
}
public MyIterator<T> iterate(){
return new MyLinkedIterator<T>();
}
private class MyLinkedIterator<T> implements MyIterator<T>{
public boolean hasNext(){
if(anfang.giveNachfolger() != null){
return true;
}
return false;
}
public T next(){
if(anfang.giveNachfolger() != null){
return (T) anfang.giveNachfolger().t;
}
return null;
}}}
import java.util.*;
And Main:
class Main{
public static void main(String[] args){
MyList<Integer> list = new MyLinkedList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list.get(0));
MyIterator<Integer> it = list.iterate();
while(it.hasNext()){
System.out.println(it.next());
}
}}
You have infinite recursion in nextN(), leading to a stack overflow.
If you look closely at the implementation of nextN(), it repeatedly calls itself with the same argument. This continues until the JVM runs out of stack, at which point you get a StackOverflowError. The stack trace at the point of the exception will mention nextN() many times.
Since you are not using k in the nextN function, it always calls itself with the same parameter and brings infinite loops.
Instead of that, you should call the nextN function with the member variable of k in order to iterate over them.
If you have a link like:
k -> k.nachfolger -> k.nachfolger.nachfolger -> ...
Then you need to change your function with this:
private int nextN(Knoten k){
if (k.nachfolger != null){
return nextN(k.nachfolger) + 1;
}
return 1;
}
Related
I'm new here and I have a problem.
I'm trying to implement a Comparator to compare two stacks by top.
The code looks like this
class Comp implements Comparator<Stack<Integer>> {
#Override
public int compare(Stack<Integer> st1,Stack <Integer> st2) {
return st1.peek()-st2.peek();
}
}
I got java.util.EmptyStackException at st1.peek()-st2.peek(); and I don't know why. Maybe you will help me with better implementation for my problem. Thanks!
Stack.peek throws EmptyStackException when the stack is empty.
You need to check if the stack is empty before calling peek on it,
for example, if you want the empty stacks to come before non-empty ones:
#Override
public int compare(Stack<Integer> st1, Stack<Integer> st2) {
if (st1.isEmpty() && st2.isEmpty()) {
return 0;
}
if (st1.isEmpty()) {
return -1;
}
if (st2.isEmpty()) {
return 1;
}
return st1.peek() - st2.peek();
}
Or if you want the empty stacks to come after the non-empty ones:
#Override
public int compare(Stack<Integer> st1, Stack<Integer> st2) {
if (st1.isEmpty() && st2.isEmpty()) {
return 0;
}
if (st1.isEmpty()) {
return 1;
}
if (st2.isEmpty()) {
return -1;
}
return st1.peek() - st2.peek();
}
I have made a Priority Queue class with an array list, but I am having trouble with the insert and delMin (delete minimum areas). I cannot create more functions and here is my code:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class MyMinPQ<E extends Comparable<E>> implements Iterable<E> {
private ArrayList<E> pq;
private int N;
public MyMinPQ() {
pq = new ArrayList<E>();
}
public E delMin(){
E minVal = min();
pq.remove(0);
N--;
return minVal;
}
public E min (){
if (isEmpty())
throw new NoSuchElementException();
return pq.get(0);
}
public void insert (E item){
for (int i = 0; i < N; i++){
pq.add(item);
if (pq.get(i) > pq.get(i+1)) {
E tmp = pq.get(i);
pq.set(i+1, tmp);
}
}
N++;
}
public boolean isEmpty() {
return N == 0;
}
public int size() {
return N;
}
public Iterator<E> iterator() {
return new Iterator<E>(){
int current = 0;
public boolean hasNext() {
return current != size();
}
public E next() {
if (hasNext())
return pq.get(current++);
else throw new NoSuchElementException( );
}
public void remove() {
throw new UnsupportedOperationException( );
}
};
}
}
At the insert portion of the code, I know that I have to sort the new additions to Arraylist but I am having issues with going about this. I tried to compare the values that is within the list, but eclipse does not allow it based on how I formatted it. When I use compareTo, it does not work with my iterator and everything goes into disarray.
My question is how can I go about modifying my insert function so it can sort new items in descending order? Will my delMin() also have to change because of it?
try this
public void insert(E item) {
int i = 0;
while (i < N && pq.get(i).compareTo(item) <= 0) {
i++;
}
N++;
}
Flatten an iterator of iterators in Java. If the input is [ [1,2], [3,[4,5]], 6], it should return [1,2,3,4,5,6]. Implement hasNext() and next(). Be careful when the inner iterator or list is empty.
I don't think my code works for multiple levels of inner lists.
public class FlattenList {
int index = 0; // keep an index to indicate where the current accessed element is
List<Integer> flattenedList = new ArrayList<>(); // flattenedList
public FlattenList(List<List<Integer>> lists){
for(List<Integer> list : lists){ // add all inner list to our underlying list.
flattenedList.addAll(list);
}
}
public boolean hasNext(){ // check if the index has exceeded the list size
return flattenedList.size() > index? true : false;
}
public Integer next(){ // return the next element, and increment the index
Integer result = flattenedList.get(index);
index++;
return result;
}
}
So basically this is like writing a depth first traversal of a tree. Leaf nodes of this tree are numbers, all interior nodes are modeled as Iterators. Here is some pseudo code:
void flatten(Iterator<Object> iterator, List<Integer> flattenedList) {
for (Object o : iterator) {
if (o instanceof Iterator) {
flatten((Iterator) o, flattenedList);
} else {
flattenedList.add((Integer) o);
}
}
}
Here, I'll start it for you:
public <T> Iterator<T> flatten(final Iterator<Iterator<T>> iterators) {
if (iterators == null) {
throw new IllegalArgumentException("iterators can't be null");
}
return new Iterator<>() {
#Override
public boolean hasNext() {
throw new UnsupportedOperationException("Not implemented: hasNext");
}
#Override
public T next() {
throw new UnsupportedOperationException("Not implemented: next");
}
};
}
Now you just do that pesky brainwork and you'll be done.
EDIT
If you're not used to that syntax, here's a slightly easier one:
public <T> Iterator<T> flatten(final Iterator<Iterator<T>> iterators) {
return new MyFlatteningIterator<>(iterators);
}
public class MyFlatteningIterator<T> implements Iterator<T> {
private final Iterator<Iterator<T>> iterators;
public MyFlatteningIterator(final Iterator<Iterator<T>> iterators) {
if (iterators == null) {
throw new IllegalArgumentException("iterators can't be null");
}
this.iterators = iterators;
}
#Override
public boolean hasNext() {
throw new UnsupportedOperationException("Not implemented: hasNext");
}
#Override
public T next() {
throw new UnsupportedOperationException("Not implemented: next");
}
}
You should not treat this as a list, rather as Jon stated this is more suitable when you are talking about trees. If you infect looking for a solution to get a flatted iterator of list of lists (something that looks like [[1],[1,2,3],[8,9]]) then I think that the following solution will work better
import java.util.Collection;
import java.util.Iterator;
public class FlattedIterator<T> implements Iterator<T> {
private Iterator<T>[] iteratorsArray;
public FlattedIterator(Collection<T>[] items) {
this.iteratorsArray = new Iterator[items.length];
for(int index = 0; index < items.length; index++) {
this.iteratorsArray[index] = items[index].iterator();
}
}
#Override
public boolean hasNext() {
boolean hasNext = false;
for(int index = 0; index < this.iteratorsArray.length; index++) {
hasNext |= this.iteratorsArray[index].hasNext();
}
return hasNext;
}
#Override
public T next() {
int index = 0;
while(index < this.iteratorsArray.length && !this.iteratorsArray[index].hasNext()) {
index++;
}
if(index >= this.iteratorsArray.length ) {
throw new IndexOutOfBoundsException("Reached end of iterator");
}
return this.iteratorsArray[index].next();
}
}
Bear in mind that the reason that I think this solution will work better is due to the fact that in your solution you initialized flattenedList by adding all the data from the given lists meaning that if in some point of the program one of those lists will received more data after you initialized FlattenList then the new data wont appear while you read the iterator.
I am trying to change the data portion of a node, but I am getting a cannot find symbol error on my sets and gets for the WordItem class. The first part is the object class and the containsWord is in the LinkedList class. Any help would be appreciated.
public class WordItem implements Comparable {
private String word;
private int count;
private ArrayList<Integer> atLines;
public WordItem(String word, int c, int atLine) {
this.word = word;
this.count = c;
this.atLines = new ArrayList<Integer>();
atLines.add(atLine);
}
#Override
public int compareTo(Object other) {
WordItem w = (WordItem)other;
return w.getWord().compareTo(this.word);
}
public String getWord() {
return this.word;
}
public int getCount() {
return this.count;
}
public void setCount(int count){
this.count = count;
}
public void setAtLines(int line){
this.atLines.add(line);
}
public boolean containWord(String word, int atLine){
Node curr,prev;
boolean flag = false;
prev = head;
for(curr = head.next; curr != null; curr = curr.next){
if(word.equals(curr.data.getWord())){
ArrayList<Integer> ara = curr.data.getLines();
for(int i = 0; i < ara.size(); i++){
if(ara.get(i) == atLine){
curr.data.setCount(curr.data.getCount() + 1);
return true;
}
}
curr.data.setAtLines(atLine);
curr.data.setCount(curr.data.getCount() + 1);
return true;
}
prev = curr;
}
return false;
}
I don't see any problems in the code. I ran it and I can't reproduce the error.
It might be that your IDE got stuck. Try to Clean/Build and if that doesn't help try resetting/clearing the cache (google for that, how to do that is different with every IDE).
From the code you have posted, there is no method WordItem#getLines().
I assume that you may have just not copied all the code in your question, but just to make sure that you do have this method within your WordItem class
public ArrayList<Integer> getLines(){
return atLines;
}
If not then the following line
ArrayList<Integer> ara = curr.data.getLines();
will fail.
I think you maybe have a little typo somewhere, if you see the definition of the error: http://java.about.com/od/cerrmsg/g/Definition-Cannot-Find-Symbol.htm
That may be the problem
Recently have found such java-concurrency interview task:
Write simple lock-free Stack with two methods: push and pop.
I made the concent:
import java.util.concurrent.atomic.AtomicInteger;
public class Stack {
private AtomicInteger count = new AtomicInteger(-1);
private Object[] data = new Object[1000];
public void push(Object o) {
int c = count.incrementAndGet();
data[c] = o;
}
public Object pop() {
Object top;
int c;
while (true) {
c = count.get();
if (c == -1) return null;
top = data[c];
if (count.compareAndSet(c, c-1))
return top;
}
}
}
Is it similar to approach was expected? Or "lock-free stack" means something different? Please, help a java-interview newbie.
You've certainly started in the right direction, thinking about using Java's atomic integer and atomic functions. That would thus be a lock-free stack, as in: there are no explicit locks.
It is still not correct when concurrently accessed, however, and it's relatively simple to demonstrate that: imagine your push() thread blocks between getting the count and adding the new element to the stack (data[c] = o), and in the meantime a pop() thread comes along, gets the higher count, and pops... What? Whatever happens to be in memory at that location in the stack, but not the Object o (because it wasn't yet inserted).
And that's the problem with lock-free, array-backed stacks, that you have two things you theoretically need to adjust, the count and the content of that particular cell, and you can't do both atomically at the same time. I'm not aware of any lock-free array-backed stack algorithm out there.
There are linked-list-backed stack algorithms though that are lock-free, because in that case you can create a new node, assign it the content, and you only have one operation to execute atomically: change the top pointer.
If you're interested in the argument, the best literary work is Shavit and Herlihy's "The Art of Multiprocessor Programming", which describes lots of different data structures, both lock-free and lock-based. I can't find any paper right now describing the "usual" lock-free stack algorithm in detail, though Maged Michael mentions it in his SMR paper, page 8, point 4.2, and I have done a C99 implementation myself.
import java.util.Random;
import java.util.concurrent.atomic.AtomicReference;
public class LockFreeStack {
public static void main(String... args) {
LFStack<String> stack = new LFStack<String>();
for (int i = 0; i < 10; i++) {
Thread t = new Thread(new RandomStackUse(stack));
t.setName("My stack thread " + i);
t.start();
}
}
private static class LFStack<E> {
private volatile AtomicReference<Node<E>> head = new AtomicReference<Node<E>>();
public E peek() {
E payload = null;
Node<E> node = head.get();
if (node != null) { payload = node.payload; }
return payload;
}
public E pop() {
E payload;
while (true) {
Node<E> oldHeadNode = head.get();
if (oldHeadNode == null) { return null; }
payload = head.get().payload;
if (head.compareAndSet(oldHeadNode, oldHeadNode.next.get())) { break; }
//System.out.println("Retry");
}
return payload;
}
public void push(E e) {
Node<E> oldHeadNode = new Node<E>(e);
while (true) {
Node<E> oldRootNode = head.get();
if (oldRootNode != null) { oldHeadNode.next.set(oldRootNode); }
if (head.compareAndSet(oldRootNode, oldHeadNode)) { break; }
//System.out.println("Retry");
}
}
}
//to be used as LinkedList chain <Node> => <Node> => <Node> => null
private static class Node<E> {
private E payload;
private AtomicReference<Node<E>> next;
public Node(E e) {
payload = e;
next = new AtomicReference<Node<E>>();
}
}
public static class RandomStackUse implements Runnable {
private LFStack<String> stack;
private Random rand = new Random();
public RandomStackUse(LFStack<String> stack) {this.stack = stack;}
#Override
public void run() {
long counter = 0;
while (true) {
if (rand.nextInt() % 3 == 0) {
stack.push(String.valueOf(counter++));
//System.out.println(String.format("%s pushed %d", Thread.currentThread().getName(), counter));
}
if (rand.nextInt() % 3 == 1) {
String value = stack.pop();
//System.out.println(String.format("%s pop %s", Thread.currentThread().getName(), value));
}
if (rand.nextInt() % 3 == 2) {
String value = stack.peek();
//System.out.println(String.format("%s peek %s", Thread.currentThread().getName(), value));
}
}
}
}
}
public class MyConcurrentStack<T>
{
private AtomicReference<Node> head = new AtomicReference<Node>();
public MyConcurrentStack()
{
}
public void push(T t)
{
Node<T> n = new Node<T>(t);
Node<T> current;
do
{
current = head.get();
n.setNext(current);
}while(!head.compareAndSet(current, n));
}
public T pop()
{
Node<T> currentHead = null;
Node<T> futureHead = null;
do
{
currentHead = head.get();
if(currentHead == null)
{
return null;
}
futureHead = currentHead.next;
}while(!head.compareAndSet(currentHead, futureHead));
return currentHead.data;
}
public T peek()
{
Node<T> n = head.get();
if(n==null)
{
return null;
}
else
{
return n.data;
}
}
private static class Node<T>
{
private final T data;
private Node<T> next;
private Node(T data)
{
this.data = data;
}
private void setNext(Node next)
{
this.next = next;
}
}
public static void main(String[] args)
{
MyConcurrentStack m = new MyConcurrentStack();
m.push(12);
m.push(13);
m.push(15);
System.out.println(m.pop());
System.out.println(m.pop());
System.out.println(m.pop());
System.out.println(m.pop());
}
}
The code is self explanatory. Please let me know if anybody needs explanation.
The stack is formed as per the following diagram:
... ... ...
| |-->| | -->| |
... ... ...
^
|
current head
You can use BlockingQueue Use method put() to insert the element and method drainTo(Collection c) to get elements. Then read elements from the end of c.