Java 无限循环检测

Java 无限循环检测,java,infinite-loop,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,我们应该打印“数字是幸运的!”如果不是,它将陷入无限循环,我们应该打印“数字不是幸运的!”

我想知道是否有可能用基本的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;
    }
}  
}
import java.util.Scanner;
公共级维兹巴{
公共静态void main(字符串[]args){
布尔运行=真;
扫描仪sc=新的扫描仪(System.in);
int number=sc.nextInt();
整数位数;
整数和=0;
int k=10;
int j=1;
while(运行){
如果(数字0){
位数=数字%k/j;
j*=10;
k*=10;
蓝--;
总和+=位数*位数;
}
/*重复此过程,直到总和为1*/
而(总和>1){
int len2=String.valueOf(sum.length();
int-pom=1;
int k1=10;
而(len2>0){
数字=总和%k1/pom;
pom*=10;
k1*=10;
len2--;
总和+=位数*位数;
}
}
System.out.println(“数字是幸运的!”);
运行=错误;
}
}  
}


一般来说,停车问题没有解决方案

然而,在您的特定情况下,我可以想出一种检测无限循环的方法。在每次迭代中,计算一个数字(数字的平方和或上一个数字)。你可以把所有这些数字放在一起。如果在某个迭代中,您计算的数字已经在该集合中,您就知道您陷入了一个无限循环


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

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

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.
Set previous=new HashSet();
//在你的循环中
整数和,数字;
做{
总和=0;
int len=String.valueOf(number).length();
/*取出每个数字以进行第一个和(可能是多余的,但请忽略)*/
而(len>0){
位数=数字%k/j;
j*=10;
k*=10;
蓝--;
总和+=位数*位数;
}
}while(sum>1&&previous.add(sum))
如果(总和>1)//不走运。

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

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

第一个问题-链是否会无限延伸?如果您有一个n位数字,则下一个数字将小于81*n-这是999999之后的下一个值。。当n>2时,81n<100n<10^n,且所有n位数字均小于10^n。因此链是有界的,必须终止或重复

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


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

也许您可以使用以下内容:

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

如果您碰巧以某种方式解决了它,请准备接受几个奖励:。您不能为无限循环提供通用检测。最好生成一个不能进入无限循环的穷举解。一个解决办法是设置一个时间限制或循环计数限制,但这并不理想。如果你两次击中同一个数字,你就知道你在循环中,虽然这不包括朝正或负无穷大的方向前进。这是我所想的,但是如果数字朝正或负无穷大的方向前进,会怎么样(或者对一个固定点有更大的震荡)。你必须证明它不能做到这一点(或者设置最小/最大界限)@RichardTingle
int
的范围是有界的,当然这并不是真的有帮助;)我得说,对于我们的知识水平来说,这只是一项写得很糟糕的任务。第一次听到这个东西听起来很酷,但我渴望学习,所以它很棒:D是的,你的解决方案听起来像是本例中唯一的解决方案谢谢:)@Peter true,实际上,即使使用bigInt,最终也会耗尽内存,但我不确定是否会将其视为捕捉无穷大loop@RichardTingle数字的平方和总是正的,因为整数最多有10个数字,所以平方和小于810。这意味着集合最多包含810个数字,并且程序最多在810次迭代后终止。感谢帮助,看起来我将使用集合:)