Java:在链表中添加数字会产生奇怪的结果

时间:2016-02-25 19:05:26

标签: java linked-list

我必须编写一个程序,在一个LinkedLists数组中存储多达10个任意长的数字,然后将它们加在一起,将它们存储在第11个列表中,然后输出结果。我已经编写了所有代码,但是当我打印出结果时,我得到了不稳定的结果。这是我的代码:

import java.util.*;

public class LongNumbers {

   private List<Integer> [] theLists;

   public LongNumbers(){
   this.theLists = new LinkedList[11];
   for (int i=0; i<11; i++)
   this.theLists[i]= new LinkedList<>();
}

public void add(int location, int digit)
{
//add digit at head of LinkedList given by location
theLists[location].add(digit);
}
public int remove(int location)
{
//remove a digit from LinkedList given by location
    return theLists[location].remove(location);
}
public boolean isEmpty(int location)
{
//check for an empty LinkedList given by location
return theLists[location].isEmpty();
}

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

//local variables
String number;
boolean userWantsToQuit = false;
LongNumbers lists = new LongNumbers();
int currArrayLocation = 0;
int currDigit = 0;
int maxLength = 0;
int numsEntered = 0;
int finalDigit = 0;
int carryDigit = 0;
char[] digits;

//get data
do{
System.out.println("Enter a number, or enter -1 to escape.");
number = kb.nextLine();

if(number.equals("-1"))
    userWantsToQuit = true;
else {
    numsEntered++;
    if (number.length()> maxLength) 
        maxLength = number.length();
    digits = new char[number.length()]; 
    for (int i = 0; i < number.length(); i++){
        digits[i] = number.charAt(i);
        currDigit = digits[i]-48;
        lists.add(currArrayLocation, currDigit);}
    } 
    currArrayLocation++;

} while (!userWantsToQuit && currArrayLocation < 9 );
//if the linkedLists are full
if (currArrayLocation == 9)
    System.out.println("The max amount of numbers have been entered.");

//to add numbers into final linked list
for (int i = 0; i < maxLength; i++){
    for (currArrayLocation = 0; currArrayLocation < numsEntered; currArrayLocation++){
       if (lists.theLists[currArrayLocation]== null){
            lists.remove(0);}
            //currDigit = 0;
       else{
            currDigit = lists.theLists[currArrayLocation].get(0);
        int tempDigit = currDigit;
        System.out.println("temp: " + tempDigit); //test line
        finalDigit += tempDigit;
        System.out.println(finalDigit); //test line
        }



    //add the proper digit to the last LinkedList and set carry digit
    finalDigit = finalDigit + carryDigit;
    carryDigit = finalDigit/10;
    //lists.add(10, finalDigit);
    //lists.remove(0); 
    //finalDigit = 0;       
} 
lists.add(10, finalDigit);
lists.remove(0);
finalDigit = 0;   
}
//print the sum
if (lists.theLists[10] != null){
        System.out.print("Sum: ");
        for (int i = 0; i < lists.theLists[10].size() ; i++){
        System.out.print(lists.theLists[10].get(i));
        }
    }
}//end main
}//end class        

当我将100和200加在一起时,我得到322.我相信我的问题在评论后面的行中//将数字添加到最终链接列表中。

任何见解或想法都会很棒,请提前感谢!

1 个答案:

答案 0 :(得分:0)

是的,这个问题实际上有很多问题。

我把你的代码放在BlueJ的调试器中,经过多次痛苦的调试后,我终于找到了问题。很快我意识到你的第81行应该是:

currDigit = lists.theLists[currArrayLocation].get(i);

但如果你这样做,你得到一个IndexOutOfBoundsException,这让我困惑了一段时间,但我最终发现了有问题的第97行:

lists.remove(0);

这让我发现你的public int remove(int location)方法都错了。它唯一做的就是删除你的一个数字中的一位数。我想你的意思是这样的:

public void remove(int location)
{
    //remove a digit from LinkedList given by location
    for (int i=0; i<theLists[location].size(); i++){
        theLists[location].remove(i);
        theLists[location].add(i,0);
    }
}

注意我将返回类型更改为void,因为这里不需要返回任何内容。

但是,为什么要删除该循环结束时的任何内容呢?在完全删除第97行之后,代码与输出完全正常,如你所料:

Enter a number, or enter -1 to escape.
100
Enter a number, or enter -1 to escape.
200
Enter a number, or enter -1 to escape.
300
Enter a number, or enter -1 to escape.
-1
temp: 1
1
temp: 2
3
temp: 3
6
temp: 0
0
temp: 0
0
temp: 0
0
temp: 0
0
temp: 0
0
temp: 0
0
Sum: 600

然而,按照惯例,这又引起了另一个问题。当将不同长度的数字加在一起时,我们在第81行(我们之前修复的行)上得到另一个IndexOutOfBoundsException。事实证明这是由你的顶部循环引起的,它假设输入的每个数字都是相同的长度。为了解决这个问题,我写了一个方法,在所有数字的开头输入前导零,如下所示:

public static void bufferWithLeadingZeroes(List<Integer>[] theLists, int maxLength){
    for (int i=0; i<10; i++){
        int howManyToAdd = maxLength - theLists[i].size();
        for (int j=0; j<howManyToAdd; j++){
            theLists[i].add(0,0);
        }
    }
    theLists[10].add(0,0);
}

然后在方法调用中添加:bufferWithLeadingZeroes(lists.theLists,maxLength);到第73行

在玩完之后我发现你处理携带数字的方式完全错了,所以我写了一个循环,通过迭代lists中最后一个条目的数字来处理这个问题,将其添加到第90行:

if (finalDigit > 9){
    i++;
    int newDigit = lists.theLists[10].get(i-1) + (finalDigit/10);
    lists.theLists[10].remove(i-1);
    lists.theLists[10].add(i-1,newDigit);
    finalDigit %= 10;
    for (int j=(i-1); j>=0; j--){
        if (lists.theLists[10].get(j) > 9){
            if (j == 0){
                lists.theLists[10].add(j,0);
                j++;
                i++;
            }
            newDigit = lists.theLists[10].get(j-1) + 1;
            lists.theLists[10].remove(j-1);
            lists.theLists[10].add(j-1,newDigit);
            newDigit = lists.theLists[10].get(j) % 10;
            lists.theLists[10].remove(j);
            lists.theLists[10].add(j,newDigit);
        }
    }
    i--;
}

所以现在,最后,傻逼工作。这是(删节)输出:

Enter a number, or enter -1 to escape.
734924
Enter a number, or enter -1 to escape.
3749223749
Enter a number, or enter -1 to escape.
423
Enter a number, or enter -1 to escape.
6432842
Enter a number, or enter -1 to escape.
3294492423442424
Enter a number, or enter -1 to escape.
-1
temp: 0
0
temp: 0
0
temp: 0
0
temp: 0
0
temp: 3
3
temp: 0

...

temp: 2
18
temp: 4
22
Sum: 03294496179834362

你会注意到Sum打印的是前导零。您可能想要更改打印数字的最终循环,以便修剪它们。

最后,这是我们全面运作的代码:

    import java.util.*;

public class LongNumbers {

    private List<Integer> [] theLists;

    public LongNumbers(){
        this.theLists = new LinkedList[11];
        for (int i=0; i<11; i++)
            this.theLists[i]= new LinkedList<>();
    }

    public void add(int location, int digit)
    {
        //add digit at head of LinkedList given by location
        theLists[location].add(digit);
    }

    public void remove(int location)
    {
        //remove a digit from LinkedList given by location
        for (int i=0; i<theLists[location].size(); i++){
            theLists[location].remove(i);
            theLists[location].add(i,0);
        }
    }

    public boolean isEmpty(int location)
    {
        //check for an empty LinkedList given by location
        return theLists[location].isEmpty();
    }

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

        //local variables
        String number;
        boolean userWantsToQuit = false;
        LongNumbers lists = new LongNumbers();
        int currArrayLocation = 0;
        int currDigit = 0;
        int maxLength = 0;
        int numsEntered = 0;
        int finalDigit = 0;
        int carryDigit = 0;
        char[] digits;

        //get data
        do{
            System.out.println("Enter a number, or enter -1 to escape.");
            number = kb.nextLine();

            if(number.equals("-1"))
                userWantsToQuit = true;
            else {
                numsEntered++;
                if (number.length()> maxLength) 
                    maxLength = number.length();
                digits = new char[number.length()]; 
                for (int i = 0; i < number.length(); i++){
                    digits[i] = number.charAt(i);
                    currDigit = digits[i]-48;
                    lists.add(currArrayLocation, currDigit);}
            } 
            currArrayLocation++;

        } while (!userWantsToQuit && currArrayLocation < 9 );
        //if the linkedLists are full
        if (currArrayLocation == 9)
            System.out.println("The max amount of numbers have been entered.");
        bufferWithLeadingZeroes(lists.theLists,maxLength);
        //to add numbers into final linked list
        for (int i = 0; i < maxLength; i++){
            for (currArrayLocation = 0; currArrayLocation < numsEntered; currArrayLocation++){
                if (lists.theLists[currArrayLocation]== null){
                    lists.remove(0);}
                //currDigit = 0;
                else{
                    currDigit = lists.theLists[currArrayLocation].get(i);
                    int tempDigit = currDigit;
                    System.out.println("temp: " + tempDigit); //test line
                    finalDigit += tempDigit;
                    System.out.println(finalDigit); //test line
                }
            }
            if (finalDigit > 9){
                i++;
                int newDigit = lists.theLists[10].get(i-1) + (finalDigit/10);
                lists.theLists[10].remove(i-1);
                lists.theLists[10].add(i-1,newDigit);
                finalDigit %= 10;
                for (int j=(i-1); j>=0; j--){
                    if (lists.theLists[10].get(j) > 9){
                        if (j == 0){
                            lists.theLists[10].add(j,0);
                            j++;
                            i++;
                        }
                        newDigit = lists.theLists[10].get(j-1) + 1;
                        lists.theLists[10].remove(j-1);
                        lists.theLists[10].add(j-1,newDigit);
                        newDigit = lists.theLists[10].get(j) % 10;
                        lists.theLists[10].remove(j);
                        lists.theLists[10].add(j,newDigit);
                    }
                }
                i--;
            }
            lists.add(10, finalDigit);
            finalDigit = 0;
        }
        //print the sum
        if (lists.theLists[10] != null){
            System.out.print("Sum: ");
            for (int i = 0; i < lists.theLists[10].size() ; i++){
                System.out.print(lists.theLists[10].get(i));
            }
        }
    }//end main

    public static void bufferWithLeadingZeroes(List<Integer>[] theLists, int maxLength){
        for (int i=0; i<10; i++){
            int howManyToAdd = maxLength - theLists[i].size();
            for (int j=0; j<howManyToAdd; j++){
                theLists[i].add(0,0);
            }
        }
        theLists[10].add(0,0);
    }

}//end class