无限循环检测

时间:2015-03-06 13:46:09

标签: java infinite-loop

我想知道是否有可能使用基本的java知识检测和/或停止无限循环。

我得到了一个学校任务(认为我们的编程知识在基础水平上),我们应该从用户那里获取输入(int),然后取这个数字的数字的平方和(即123 - > 1 ^ 2 + 2 ^ 2 + 3 ^ 2)。然后该结果应该放在while循环中并且它应该重复相同的事情直到它达到1(即123 - > 1 ^ 2 + 2 ^ 2 + 3 ^ 2 = 14 - > 1 ^ 2 + 4 ^ 2 = 17 - > 1 ^ 2 + 7 ^ 2等)

如果我们得到数字1,我​​们应该打印“数字很幸运!”如果不是,它将陷入无限循环,我们应该打印“数字不幸运!”。

现在最烦我的是,如果它们陷入无限循环,他们怎么期望我们打印“数字不幸运”?

是否可能是编写和设计错误的任务/问题,或者实际上是否存在检测和停止无限循环的基本级知识方式?


这是我的代码(没有无限循环检测):

import java.util.Scanner;

public class Vezba {

public static void main(String[] args) {
    boolean run = true;
    Scanner sc = new Scanner(System.in);
    int number = sc.nextInt();
    int digits;
    int sum=0;
    int k = 10;
    int j = 1;
    while(run){
        if(number<0){
            run=false;
        }
        int len = String.valueOf(number).length();
       /* Takes out each digit to make the first sum (probably redundant but please ignore)*/
        while(len>0){
            digits = number%k/j;
            j*=10;
            k*=10;
            len--;
            sum += digits*digits;
        }
       /* Repeats the process until sum is 1*/
        while(sum>1){
            int len2 = String.valueOf(sum).length();
            int pom = 1;
            int k1=10;
            while(len2>0){
                digits = sum%k1/pom;
                pom*=10;
                k1*=10;
                len2--;
                sum += digits*digits;
            }
        }
        System.out.println("Number is lucky!");
        run=false;
    }
}  
}

5 个答案:

答案 0 :(得分:3)

一般来说,暂停问题没有解决办法。

但是,在您的具体情况下,我可以想到一种检测无限循环的方法。在每次迭代中,您计算​​一个数字(数字的平方和前一个数字的总和)。您可以将所有这些数字放在一个集合中。如果在某个迭代中你计算了一个已经存在于该集合中的数字,你知道你陷入了无限循环。

由于最大的平方和是绑定的(对于具有n个数字的数字,数字的最大平方和是81 * n),在迭代中将获得相对较少的不同值,如果你没有达到1并以成功结束,你将达到之前已经出现的值并报告失败。

答案 1 :(得分:2)

虽然您无法提供通用的无限循环检测,但您可以为此用例提供一个简单的循环检测。您可以假设,一旦重复一个数字,您将永远循环,所以您需要做的就是检测重复的数字。

Set<Integer> previous = new HashSet<>();

// in you loop
int sum, number;
do {
   sum = 0;
   int len = String.valueOf(number).length();
   /* Takes out each digit to make the first sum (probably redundant but please ignore)*/
    while(len>0){
        digits = number%k/j;
        j*=10;
        k*=10;
        len--;
        sum += digits*digits;
    }
} while (sum > 1 && previous.add(sum))
if (sum > 1) // no lucky.

在这种情况下,previous.add(sum)将返回false,检测到重复。

答案 2 :(得分:0)

唯一的方法是设置最大迭代次数或超时算法

答案 3 :(得分:0)

第一个问题 - 链条会延伸到无穷大吗?如果你有一个n位数字,那么下一个数字将小于81 * n - 这是999999之后的下一个数字.81n&lt; 100n&lt; 100n当n> 2时,10 ^ n,并且所有n位数小于10 ^ n。因此链是有界的,必须终止或重复。

第二个问题是如何检测循环。您可以存储所有访问过的值并检查它们。在这种情况下,这可能是可行的,但通常它需要大量的内存和时间来检查是否找到重复。

时间和空间上更有效的算法可以是将在步骤m / 2中找到的值存储在链中并将其与步骤m处的值进行比较。当您探索解决方案空间时,您可以将此视为拖尾一条延长的绳索。最终(如果这是一个循环)你将遇到你的字符串的结尾。

答案 4 :(得分:0)

也许你可以使用这样的东西:

n = in.nextInt();
int t = n;
while (n != 0)
{
    r = n % 10;
    s += Math.pow(r, 2);
    n /= 10;
}
if (s == t)
System.out.println(whatever is given);
else
System.out.println (whatever is given);