代码之家  ›  专栏  ›  技术社区  ›  user4833678

嵌套循环内的错误计算

  •  0
  • user4833678  · 技术社区  · 11 年前

    代码的目标是找到与 targetNumber 。例如,如果 targetNumber = 9 那么代码应该得到加起来的数字的前两个索引 目标编号 。当我运行代码时,输出如下所示:

    The indexes are 10 and 1
    

    代码的逻辑有什么问题?提前感谢!

    public class TwoSum {
    
        public static void main(String[] args){
    
            int[] myArray = {1, 6, 43, 22, 4, 6, 4, 3, 8, 7, 3};
            int targetNumber = 9;
            int index1 = 0;;
            int index2 = 0;
    
            for(int i = 0; i < myArray.length; i++){
                for(int j = 1; j < myArray.length; j++){
                    if(myArray[i] + myArray[j] == targetNumber){
                        index1 = i;
                        index2 = j;
                        break;
                    }
                }
            }
            System.out.println("The indexes are " + index1 + " and " + index2);
        }
    }
    
    5 回复  |  直到 11 年前
        1
  •  4
  •   Adam Evans    9 年前

    当你打破时,你只打破了内循环,所以不是先打印出1,然后打印出10,外循环继续,自然终止,导致打印出索引10,然后是索引1。

    这样做的一个有趣的结果是,您的代码基本上找到 最后的 一对和为 targetNumber ,而不是第一个。如果你让for循环倒计时而不是倒计时,那么代码应该输出正确的值,尽管这不是很有效。。。

        2
  •  1
  •   Shar1er80    11 年前

    我相信您期望索引0和8(值1和8)。问题是你的 break 语句只从内部循环中断,而不从外部循环中断。您需要使用一个标志来知道您也应该从外部循环中断开。如果没有找到匹配项,也可以考虑打印消息。

    public static void main(String[] args) throws Exception {
        int[] myArray = {1, 6, 43, 22, 4, 6, 4, 3, 8, 7, 3};
        int targetNumber = 9;
        int index1 = 0;
        int index2 = 0;
    
        boolean stop = false;
        for (int i = 0; i < myArray.length && !stop; i++) {
            for (int j = i + 1; j < myArray.length && !stop; j++) {
                if (myArray[i] + myArray[j] == targetNumber) {
                    stop = true;
                    index1 = i;
                    index2 = j;
                }
            }
        }
        System.out.println(stop 
                ? "The indexes are " + index1 + " and " + index2
                : "No match found");
    }
    

    或者只需在内部循环中打印结果并使用 return 而不是 打破 。这样就不必使用标志。

    public static void main(String[] args) throws Exception {
        int[] myArray = {1, 6, 43, 22, 4, 6, 4, 3, 8, 7, 3};
        int targetNumber = 9;
    
        for(int i = 0; i < myArray.length; i++){
            for(int j = i + 1; j < myArray.length; j++){
                if(myArray[i] + myArray[j] == targetNumber){
                    System.out.println("The indexes are " + i + " and " + j);
                    return;
                }
            }
        }   
        System.out.println("No match found");
    }
    

    结果:

    The indexes are 0 and 8
    
        3
  •  1
  •   Makoto    11 年前

    使代码更清晰;即完全在 break 语句,应该引入一个布尔变量 found 到你的循环。这样,如果你找到了第一场比赛,你就可以更直观地摆脱这两种比赛。

    boolean found = false;
    for(int i = 0; i < myArray.length && !found; i++){
        for(int j = 1; j < myArray.length && !found; j++){
            if(myArray[i] + myArray[j] == targetNumber){
                found = true;
                index1 = i;
                index2 = j;
            }
        }
    }
    System.out.println("The indexes are " + index1 + " and " + index2);
    

    如果你曾经好奇其他几对数字加起来是什么,那么创建一个 Pair<T> 类,可以存储此类信息。你不会打破任何循环,因为你本质上是在残酷地对待整个事情。

    class Pair<T> {
        final T firstValue;
        final T secondValue;
    
    
        Pair(T firstValue, T secondValue) {
            this.firstValue = firstValue;
            this.secondValue = secondValue;
        }
    
        public T getFirstValue() {
            return firstValue;
        }
    
        public T getSecondValue() {
            return secondValue;
        }
    
        @Override
        public String toString() {
            return "{" + firstValue + ", " + secondValue + "}";
        }
    }
    
    // later in your code
    
    
    List<Pair<Integer>> pairs = new ArrayList<>();
    
    for(int i = 0; i < myArray.length; i++){
        for(int j = 1; j < myArray.length; j++){
            if(myArray[i] + myArray[j] == targetNumber){
                pairs.add(new Pair<>(i, j));
            }
        }
    }
    System.out.println("The indexes are " + pairs);
    

    上面打印出:

    The indexes are [{0, 8}, {1, 7}, {1, 10}, {5, 7}, {5, 10}, {7, 1}, {7, 5}, {10, 1}, {10, 5}]
    
        4
  •  0
  •   DarthDerrr    11 年前

    break语句是中断内部循环,而不是外部循环。所以它得到的是3和6的最后一个结果,而不是1和8。

    更合适的方式可能是:

        bool found=false;
        for(int i = 0; i < myArray.length; i++){
            if(!found){
                for(int j = 1; j < myArray.length; j++){
                    if(myArray[i] + myArray[j] == targetNumber){ 
                        index1 = i; index2 = j;               
                        found=true; 
                        break; 
    } } }}
    
        5
  •  0
  •   Aivean    11 年前

    您的代码有三个问题:

    1. 根据规范,您希望找到第一个匹配的索引,而 你真的找到了最后一个。这是因为 break 仅打断内部循环。简单的解决方法是使用标签( outer: ). 虽然更干净的方法是使用专用方法进行搜索和 return 第一匹配值。

    2. 您检查两次索引对,同时检查同一索引对。消除这种冗余的惯用方法是从外部循环索引的当前值开始嵌套循环( j = i )或( j = i + 1 )如果您不希望有相同索引(i,i)的对。

    3. 当没有找到匹配索引时,您没有考虑这种情况。在这种情况下,您将显示(0,0)是结果。

    这里是你的代码修复:

            public static class TwoSum {
    
                public static void main(String[] args) {
                    int[] myArray = {1, 6, 43, 22, 4, 6, 4, 3, 8, 7, 3};
                    int targetNumber = 9;
                    int index1 = -1;
                    int index2 = -1;
    
                    outer:
                    for (int i = 0; i < myArray.length; i++) {
                        for (int j = i + 1; j < myArray.length; j++) {
                            if (myArray[i] + myArray[j] == targetNumber) {
                                index1 = i;
                                index2 = j;
                                break outer;
                            }
                        }
                    }
    
                    if (index1 >= 0) {
                        System.out.println("The indexes are " + index1 + " and " + index2 + "(Values " + myArray[index1] +
                                " and " + myArray[index2] + ")");
                    } else {
                        System.out.println("Not found");
                    }
                }
            }