为什么我的自定义LinkedList中的remove()方法无法正常工作?

时间:2017-10-07 03:40:15

标签: java linked-list

我很抱歉,如果这是一个非常长的代码,但唯一的问题是LinkedList类中的remove()方法,我一直在努力研究这段代码几个小时似乎无法找到解决方案。每当我为主方法输入ADD 456时,而不是打印

0+6+5+4
RESULT 15

我一直在

0+6+6+4
RESULT 16

这意味着remove()或insert()方法出错了,但是当我检查insert()方法的输入时,5必须正确插入。所以我想知道remove()方法的哪一部分出错了,以及如何解决它。感谢。

这些是接口。

接口堆栈。

package ds.stack;

public interface Stack<E> {
/*
 * Removes all of the elements in this stack.
 */
public void clear();

/*
 * Pushes an item onto the top of this stack.
 * 
 * @param item
 *            the item to be pushed onto this stack
 */
public void push(E item);

/**
 * Removes the item at the top of this stack and returns that item as the
 * value of this method.
 * 
 * @return the item at the top of this stack, or null if this stack is empty
 */
public E pop();

/**
 * Returns the number of elements in this stack.
 * 
 * @return the number of elements in this stack
 */
public int length();

/**
 * Returns true if this stack contains no elements.
 * 
 * @return true if this stack contains no elements
 */
public boolean isEmpty();
}

接口列表。

package ds.list;

public interface List<E> {
/**
 * Removes all of the elements from this list.
 */
public void clear();

/**
 * Inserts the specified element at the specified position in this list.
 * 
 * @param pos
 *            index at which the specified element is to be inserted
 * @param item
 *            element to be inserted
 */
public void insert(int pos, E item);

/**
 * Removes the element at the specified position in this list. Shifts any
 * subsequent elements to the left (subtracts one from their indices).
 * Returns the element that was removed from the list.
 * 
 * @param pos
 *            the index of the element to be removed
 * @return the element previously at the specified position
 */
public E remove(int pos);

/**
 * Returns the number of elements in this list.
 * 
 * @return the number of elements in this list.
 */
public int length();

/**
 * Returns the element at the specified position in this list.
 * 
 * @param pos
 *            index of the element to return
 * @return the element at the specified position in this list
 */
public E getValue(int pos);
}

这是我的LinkedList类

package ds.list;

public class LinkedList<E> implements List<E> {
private E element;
private LinkedList<E> next;
private LinkedList<E> head;
private LinkedList<E> tail;
private LinkedList<E> curr;
public int cnt=0;   //length of the list
/*
* constructors below
*/
public LinkedList() {   //The very initial constructor
    curr = tail = head = this;
}
public LinkedList(LinkedList<E> nextval) {  //when you start making more bundles
    next = nextval;
}

public void setNext(LinkedList<E> nextval) {
    next = nextval;
}

public void goNext() {
    curr = next;
}   // curr becomes the next bundle

public void setValue(E item) {
    element = item;
}
@Override
public void clear() {
    tail = head = new LinkedList<E>();
    next = null;
    cnt = 0;
}

@Override
public void insert(int pos, E item) {
    if(pos<0||pos>cnt+1) {
        return;
    }
    if(pos==0) {
        curr = head;
        head = new LinkedList<E>(curr);
        curr = head;
        curr.setValue(item);
    }
    curr = head;
    for(int i=0;i<pos-1;i++) {
        goNext();
    }   //curr points right before the index of pos
    LinkedList<E> temp = curr.next;
    curr.setNext(new LinkedList<E>(temp));
    curr.goNext();
    curr.setValue(item);
    cnt++;
}

@Override
public E remove(int pos) {
    if(pos<0||pos>cnt)
        return null;
    curr = head;
    if(cnt==1) {
        E it = element;
        curr = head = tail = null;
        cnt--;
        return it;
    }
    for(int i=0;i<pos-1;i++) {
        goNext();
    }
    E it = next.element;
    curr.setNext(next.next);
    cnt--;
    return it;
}

@Override
public int length() {
    return cnt;
}

@Override
public E getValue(int pos) {
    if(pos<0||pos>cnt)
        return null;
    curr = head;
    for(int i=0;i<pos-1;i++) {
        goNext();
    }
    return next.element;
}
}

这是我的LinkedStack类,使用LinkedList类

package ds.stack;

import ds.list.LinkedList;

public class LinkedStack<E> implements Stack<E> {
private LinkedList<E> stack = new LinkedList<E>();
@Override
public void clear() {
    stack.clear();
}

@Override
public void push(E item) {
    if(stack.cnt == 0) {
        stack.setValue(item);
        stack.cnt++;
        return;
    }
    stack.insert(stack.length(),item);
}

@Override
public E pop() {
    if(stack.length()==0) {
        return null;
    }
    else {
        return stack.remove(stack.length()-1);
    }
}

@Override
public int length() {
    return stack.length();
}

@Override
public boolean isEmpty() {
    if(stack.length()==0)
        return true;
    return false;
}

}

然后这是我使用LinkedStack类的BabyCalculator类

package ds.test;

import ds.stack.LinkedStack;
import ds.stack.Stack;

public class BabyCalculator {
Stack<Character> stack = new LinkedStack<Character>();
private int value=0;

public int murmurAdd(String polynomial) {
    char[] charPol=polynomial.toCharArray();
    int count=0;
    for(int i=0;i<polynomial.length();i++) {
        if(!(Character.isDigit(charPol[i])))
            count++;
    }   // This counts the total number of ( and )s.
    int numOf=count/2;
    if (numOf==0) {
        for(int i=0;i<polynomial.length();i++) {
            stack.push(charPol[i]);
        }
    }
    else {
        for(int i=0;i<numOf;i++) {
            int num1=0, num2 = 0;   //will become the index of last ( and first )
            for(int j=0;j<polynomial.length();j++) {
                if(charPol[j]=='(')
                    num1 = j;
                if(charPol[j]==')') {
                    num2 = j;
                    break;
                }
            }
            for(int index=num1+1;index<num2;index++) {
                stack.push(charPol[index]);
            }
            StringBuilder polytemp = new StringBuilder(polynomial);
            polynomial=polytemp.replace(num1, num2+1, "").toString();
        }
        if(polynomial.length()>0) {
            charPol = polynomial.toCharArray();
            for(int i=0;i<polynomial.length();i++) {
                stack.push(charPol[i]); 
            }
        }
    }
    System.out.print(value);
    while(!(stack.isEmpty())) {
            Character a = stack.pop();
            System.out.println(" a is "+a);
            value += Character.getNumericValue(a);
            System.out.print("+"+a); 
    }
    System.out.println();
    return value;
}

public int getValue() {
    // TODO Implement this method
    return value;
}

public void setValue(int newValue) {
    // TODO Implement this method
    value = newValue;
}
}

最后,使用BabyCalculator的main()方法。

package ds.test;

import java.util.Scanner;

public class Main {

public static void main(String[] args) {
    BabyCalculator babyCalculator = new BabyCalculator();
    Scanner sc = new Scanner(System.in);

    while (sc.hasNext()) {
        String command = sc.next();
        if ("ADD".equals(command)) {
            String equation = sc.next();
            babyCalculator.murmurAdd(equation);
            System.out.println("RESULT "+babyCalculator.getValue());
            // TODO
        } else if ("SHOW".equals(command)) {
            System.out.println("VALUE "+babyCalculator.getValue());
            // TODO
        } else if ("CLEAR".equals(command)) {
            babyCalculator.setValue(0);
            System.out.println("VALUE CLEARED");
            // TODO
        } else if ("SET".equals(command)) {
            int newValue = sc.nextInt();
            babyCalculator.setValue(newValue);
            System.out.println("VALUE SET TO "+babyCalculator.getValue());
            // TODO
        } else if ("EXIT".equals(command)) {
            System.out.println("FINAL VALUE "+ babyCalculator.getValue());
            return;
            // TODO
        }
    }
    sc.close();
}
}

编辑:当我尝试ADD(2345)时,结果是

0+5+5+5+2
RESULT 17

这意味着只有2个弹出时才会弹出。为什么会这种情况继续发生?我认为它在LinkedList类中是一个深刻的指向问题。

2 个答案:

答案 0 :(得分:1)

好吧,我可以肯定地说你的LinkedList没有正确实施。在构建基础类之前,您需要对基础类进行单元测试。基本测试只涉及将几个元素插入位置0然后尝试获取位置0,1和2中的项目值失败。

这是我写的一个基本测试,它失败了NullPointerException

LinkedList<String> list = new LinkedList<>();
list.insert(0, "A");
list.insert(0, "B");
list.insert(0, "C");

System.out.println(list.getValue(0));
System.out.println(list.getValue(1));
System.out.println(list.getValue(2));

在整个代码中添加更多日志记录,使用调试器,在类上实现toString方法来帮助您找到问题。

我可以告诉您,LinkedList方法getValue无效。为了让我的测试在上面工作,我不得不改变:

for(int i=0;i<pos-1;i++) {
    goNext();
}
return next.element;

到此:

for (int i = 0; i < pos; i++) {
    goNext();
}
return curr.element;

原因是因为“next”指的是你调用LinkedList的{​​{1}}的下一个元素,而不是当前的{@}}之后的下一个元素。

我还可以告诉您getValue goNext方法中存在类似的错误:

LinkedList

应该是:

public void goNext() {
    curr = next;
}

这个类几乎肯定有更多的问题,所以我强烈建议你彻底测试和调试它,因为这可能会解决你的许多问题。

答案 1 :(得分:0)

我看到的问题多于一个问题。插入错误,删除错误(您可以通过在同一次运行中调用ADD两次来验证)。

其中一个问题是在插入中我更改了您的代码,如下所示:

//LinkedList<E> temp = curr.next;
    //curr.setNext(new LinkedList<E>(temp));
    LinkedList<E> temp = new LinkedList<E>(curr.next);
    temp.setValue(curr.element);

删除了循环

for(int i=0;i<pos-1;i++) {
    goNext();
}

在删除方法中,Atleast添加测试工作。但是你手头有更多问题。我没有测试过很多其他用例。