使用 rnd 值防止无限循环

Prevent a endless loop with rnd values

我曾经在数学上有一个叫做 computewall 的东西(德语:"Rechenwand",我不知道英语怎么说),你得到一个金字塔和一些结果。看起来例如像这样:

    0
   0|0
  0|0|0
 4|0|0|0
5|9|0|0|0

因为我有假期,所以我想:"Well let's code a bit"。所以我试着写了一个程序来计算我在金字塔中数字 1-15 只出现一次的一个解决方案。

两个数字之间的上一行数字的结果计算方式如左下角所示。是下面数字代入的绝对值。

我尝试这个的项目在 Github 上,可以在这里找到:https://github.com/SchoolGuy/Computewall

问题是每次我 运行 程序都会在 l.57 循环 do-while 导致类似无限循环的事情(实际上只是无休止地尝试适应参数)。我的问题是如何解决这个问题!

P.S.: 注释了很多找准点,大家不要怕大小

编辑 02.04.2016 15:50:

package Main;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;

public class computewall {

int[][] computewallInt = null;
int count;
ArrayList<Integer> sortedComputewall = null;
Random rnd = new Random();

public computewall() {
    count = 0;
    sortedComputewall = new ArrayList<>();
    computewallInt = new int[5][5];
    computewallInt[0][0] = 0;
    computewallInt[1][0] = 0;
    computewallInt[1][1] = 0;
    computewallInt[2][0] = 0;
    computewallInt[2][1] = 0;
    computewallInt[2][2] = 0;
    computewallInt[3][0] = 0;
    computewallInt[3][1] = 0;
    computewallInt[3][2] = 0;
    computewallInt[3][3] = 0;
    computewallInt[4][0] = 0;
    computewallInt[4][1] = 0;
    computewallInt[4][2] = 0;
    computewallInt[4][3] = 0;
    computewallInt[4][4] = 0;
    calculate();
    System.out.println("Rounds till solved: " + count);
    System.out.println("        " + computewallInt[0][0]);
    System.out.println("      " + computewallInt[1][0] + " | " + computewallInt[1][1]);
    System.out.println("    " + computewallInt[2][0] + " | " + computewallInt[2][1] + " | " + computewallInt[2][2]);
    System.out.println("  " + computewallInt[3][0] + " | " + computewallInt[3][1] + " | " + computewallInt[3][2] + " | " + computewallInt[3][3] + " | ");
    System.out.println(computewallInt[4][0] + " | " + computewallInt[4][1] + " | " + computewallInt[4][2] + " | " + computewallInt[4][3] + " | " + computewallInt[4][4]);
}

public void calculate() {
    boolean uniqueCheck = false;
    ArrayList<String> usedPosibilities = new ArrayList<>();
    System.out.println("-------------------------");
    do {
        count++;
        sortedComputewall.clear();
        boolean duplicateCheck = false;
        boolean ohCheck = false;
        //Set values and search for duplicates and 0
        do {
            computewallValueReplace(computewallInt, 4, 0, rnd.nextInt(16));
            computewallValueReplace(computewallInt, 4, 1, rnd.nextInt(16));
            computewallValueReplace(computewallInt, 4, 2, rnd.nextInt(16));
            computewallValueReplace(computewallInt, 4, 3, rnd.nextInt(16));
            computewallValueReplace(computewallInt, 4, 4, rnd.nextInt(16));
            ///*
            if (computewallInt[4][0] == computewallInt[4][1] | computewallInt[4][0] == computewallInt[4][2] | computewallInt[4][0] == computewallInt[4][3] | computewallInt[4][0] == computewallInt[4][4]
                    | computewallInt[4][1] == computewallInt[4][2] | computewallInt[4][1] == computewallInt[4][3] | computewallInt[4][1] == computewallInt[4][4]
                    | computewallInt[4][2] == computewallInt[4][3] | computewallInt[4][2] == computewallInt[4][4] | computewallInt[4][3] == computewallInt[4][4]) {
                duplicateCheck = true;
            }
            if (computewallInt[4][0] == 0 | (computewallInt[4][1] == 0) | (computewallInt[4][1] == 0) | (computewallInt[4][3] == 0) | computewallInt[4][4] == 0) {
                ohCheck = true;
            }
        } while (duplicateCheck | ohCheck);
        usedPosibilities.add(String.valueOf(computewallInt [4][0]) + String.valueOf(computewallInt [4][1]) + String.valueOf(computewallInt [4][2])
                + String.valueOf(computewallInt [4][3]) + String.valueOf(computewallInt [4][4]));
        System.out.println("Lowest row calculated");

        //Rest of calculating
        computewallInt[3][0] = Math.abs(computewallInt[4][0] - computewallInt[4][1]);
        computewallInt[3][1] = Math.abs(computewallInt[4][1] - computewallInt[4][2]);
        computewallInt[3][2] = Math.abs(computewallInt[4][2] - computewallInt[4][3]);
        computewallInt[3][3] = Math.abs(computewallInt[4][3] - computewallInt[4][4]);
        computewallInt[2][0] = Math.abs(computewallInt[3][0] - computewallInt[3][1]);
        computewallInt[2][1] = Math.abs(computewallInt[3][1] - computewallInt[3][2]);
        computewallInt[2][2] = Math.abs(computewallInt[3][2] - computewallInt[3][3]);
        computewallInt[1][0] = Math.abs(computewallInt[2][0] - computewallInt[2][1]);
        computewallInt[1][1] = Math.abs(computewallInt[2][1] - computewallInt[2][2]);
        computewallInt[0][0] = Math.abs(computewallInt[1][0] - computewallInt[1][1]);
        System.out.println("Rest of table calculated");
        sortedComputewall.add(computewallInt[0][0]);
        sortedComputewall.add(computewallInt[1][0]);
        sortedComputewall.add(computewallInt[1][1]);
        sortedComputewall.add(computewallInt[2][0]);
        sortedComputewall.add(computewallInt[2][1]);
        sortedComputewall.add(computewallInt[2][2]);
        sortedComputewall.add(computewallInt[3][0]);
        sortedComputewall.add(computewallInt[3][1]);
        sortedComputewall.add(computewallInt[3][2]);
        sortedComputewall.add(computewallInt[3][3]);
        sortedComputewall.add(computewallInt[3][3]);
        sortedComputewall.add(computewallInt[4][4]);
        sortedComputewall.add(computewallInt[4][1]);
        sortedComputewall.add(computewallInt[4][2]);
        sortedComputewall.add(computewallInt[4][3]);
        Object[] sortedComputeWallInt = sortedComputewall.toArray();
        Arrays.sort(sortedComputeWallInt);
        if (sortedComputewall.contains(0) | !sortedComputewall.contains(1) | !sortedComputewall.contains(2) | !sortedComputewall.contains(3) | !sortedComputewall.contains(4) |
                !sortedComputewall.contains(5) | !sortedComputewall.contains(6) | !sortedComputewall.contains(7) | !sortedComputewall.contains(8) | !sortedComputewall.contains(9) |
                !sortedComputewall.contains(10) | !sortedComputewall.contains(11) | !sortedComputewall.contains(12) | !sortedComputewall.contains(13) | !sortedComputewall.contains(14) |
                !sortedComputewall.contains(15)) {
            uniqueCheck = true;
        }
        System.out.println("-------------------------");
    } while (uniqueCheck);
}

public void computewallValueReplace(int[][] array, int row, int position, int value) {
    array[row][position] = value;
}
}

这是完整的 class。

当其中一项检查(duplicateCheck | ohCheck)为真时,var 从未设置为假,所以我陷入了无限循环

这段代码有一些大问题,但我会回答你关于 while 循环的具体问题。这是您的代码:

    do {
        computewallValueReplace(computewallInt, 4, 0, rnd.nextInt(16));
        computewallValueReplace(computewallInt, 4, 1, rnd.nextInt(16));
        computewallValueReplace(computewallInt, 4, 2, rnd.nextInt(16));
        computewallValueReplace(computewallInt, 4, 3, rnd.nextInt(16));
        computewallValueReplace(computewallInt, 4, 4, rnd.nextInt(16));
        ///*
        if (computewallInt[4][0] == computewallInt[4][1] | computewallInt[4][0] == computewallInt[4][2] | computewallInt[4][0] == computewallInt[4][3] | computewallInt[4][0] == computewallInt[4][4]
                | computewallInt[4][1] == computewallInt[4][2] | computewallInt[4][1] == computewallInt[4][3] | computewallInt[4][1] == computewallInt[4][4]
                | computewallInt[4][2] == computewallInt[4][3] | computewallInt[4][2] == computewallInt[4][4] | computewallInt[4][3] == computewallInt[4][4]) {
            duplicateCheck = true;
        }
        if (computewallInt[4][0] == 0 | (computewallInt[4][1] == 0) | (computewallInt[4][1] == 0) | (computewallInt[4][3] == 0) | computewallInt[4][4] == 0) {
            ohCheck = true;
        }
    } while (duplicateCheck | ohCheck);

请注意,如果在此 do-while 的第一遍中 duplicateCheckohCheck 设置为 true,那么您将陷入无限循环。它们以 false 的形式进入循环,但可以在循环的第一遍中设置为 true。循环中没有条件会将它们中的任何一个设置为 false,因此条件 (duplicateCheck | ohCheck) 将始终得到满足。