如何在我的java代码中删除这些嵌套的for循环?

时间:2017-02-27 23:36:50

标签: java

我在算法课程中,我们需要通过将其加载到链接列表中来制作一个添加了很长编号的程序。我在网上看到很多只使用两个链接列表的例子,但是我需要的不仅仅是两个数字。

import java.util.*;


public class longNumbersLinkedListCompleted
{

public static void main(String[] args)
{
    Scanner stdIn = new Scanner(System.in);
    String longNumber = "";
    LinkedList mainList = new LinkedList();
    LinkedList sumList = new LinkedList();
    LinkedList temp = null;

    //declare other variables
    int sum = 0;
    int carry= 0;
    int maxWidth = 0;

    System.out.println("Enter a Number");
    longNumber = stdIn.nextLine();
    //repeatedly input longNumbers, using -1 to indicate that you are done
    while(!longNumber.equals("-1")){

        //add a new LinkedList at the beginning of the mainList
        mainList.addFirst(new LinkedList());

        //use get(0) to set temp to be this new LinkedList
        temp = (LinkedList) mainList.get(0);

        //for each character in your longNumber, subtract 48 to get the digit and then add it
        //at the beginning of temp
        for (int i = 0; i < longNumber.length(); i++){
            temp.addFirst((int)(longNumber.charAt(i)-48));        
        }

        //keep track of maxWidth, the number of digits of the widest longNumber input so far
        if(maxWidth < longNumber.length()){
            maxWidth = longNumber.length();
        }

        System.out.println("Enter a Number");
        longNumber = stdIn.nextLine();
    }

    //make maxWidth passes
    //initialize carry to be 0
    //in each pass, loop through all of the LinkedLists in mainList
    //for each one, let temp be the Linked List for one longNumber
    //if temp is not empty, remove its first entry and add to the sum
    for(int i = 0; i < maxWidth; i++){
        sum = 0;

        for(int j = 0; j < mainList.size(); j++){
            temp = (LinkedList)mainList.get(j);
            if(temp.size() > 0){
                sum += (int)temp.removeFirst();
            }
        }
        //add sum%10 at the beginning of sumList
        //set carry equal to sum/10 (integer division)
        sumList.addFirst((sum+carry)%10);
        carry = (sum + carry) / 10;
    }

    //Now ready for output
    //if carry at the end of processing is not 0, print it and stay on the same line
    //repeatedly remove one digit from the beginning of sumList until all have been removed
    //for each, add a 48 to get a character and print it out on the same line
    if(carry != 0){
        System.out.print(carry);
    }
    for(int i = sumList.size(); i > 0; i--){
        System.out.print((char)((int)sumList.removeFirst()+48));
    }

    //remove the digits from sumList until empty

}//end main

} //结束课

这些评论来自教授,所以听起来有点像他想要一个嵌套的for循环,但今天在课堂上他提到不使用它们,而且因为整个课程都是为了让代码更好,所以这似乎是违反直觉的。使用“O(n ^ 2)”的东西。

感谢大家给予的任何帮助!

1 个答案:

答案 0 :(得分:0)

我可以看到避免嵌套for循环的唯一方法是在读取长数字时进行转置,即在你进行的过程中在while循环中构建总和。

类似的东西:

List<Integer> sums = new ArrayList<>();
while(!longNumber.equals("-1")){
  for (int i = 0; i < longNumber.length(); ++i) {
    // Process the digits in reverse.
    int digit = Character.getNumericValue(longNumber.charAt(longNumber.length() - 1 - i));

    if (i >= sums.length()) {
      sums.add(digit);
    } else {
      sums.set(i, sums.get(i) + digit);
    }
  }

  longNumber = stdIn.nextLine();
}

(请注意,这仍然是一个嵌套循环;你必须这样做才能循环,直到你读完所有数字,然后读取这些数字中的每一个数字。)

然后,下面的内部嵌套for循环是不必要的,因为已经计算了总和:

// This is the equivalent of the for(int i = 0; i < maxWidth; i++){ loop.
for (int sum : sums) {
  sumList.addFirst((sum+carry)%10);
  carry = (sum + carry) / 10;
}

(当然,您也可以将第二个循环折叠到while循环中,并且完全避免创建sums