繁体   English   中英

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

[英]How can I remove these nested for-loops in my java code?

我在算法课程中,我们需要制作一个程序,通过将它们加载到链接列表中来进行非常长的加法运算。 我在网上看到了很多仅使用两个链表的示例,但是我的示例不仅仅需要两个数字。

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)。

感谢您提供的任何帮助!

我看到的避免嵌套的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 )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM