为什么我的 Java 程序会因某些值而陷入无限的 while 循环?

Why is my Java program stuck in a infinite while-loop for some values?

我刚开始 java,当我做一个练习(关于找到给定日期后的下一个星期五 13 号)时,我遇到了以下问题:当输入日期(给定的) date) 等于或大于 13,程序进入无限循环。有什么建议吗?

      public class NextFriday13 {
    public static void main(String[] args) {
        int d = Integer.parseInt(args[0]);
        int m = Integer.parseInt(args[1]);
        int y = Integer.parseInt(args[2]);

        //aqui colocaremos o total de dias em cada mes
        int[] DAYS = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        //fixaremos nosso ponto de referencia, 1/1/1600 foi um sabado.
        int dd = 1;
        int mm = 1;
        int yy = 1600;
        int day = 0;


        //descobriremos a proxima sexta-feira 13

        while (dd <= d || mm <= m || yy <= y || day != 6 || dd != 13){
            day++;
            day %= 7;

            boolean leapYear;
            if (yy % 400 == 0) leapYear = true;
            else if (yy % 100 == 0) leapYear = false;
            else leapYear = yy % 4 == 0;

            if (dd + 1 <= DAYS[mm] || (dd == 28 && leapYear))
                dd++;
            else{
                if (mm < 12) {
                    dd = 1;
                    mm++;
                }
                else {
                    dd = 1;
                    mm = 1;
                    yy++;
                }
            }

        }
        System.out.println("Next Friday 13th is " + dd + "/" + mm + "/"+ yy);

    }
}

这是我得到的以下输入输出: input:1 1 2000 output:Next 13 号星期五是 13/4/2001

输入:6 2 2011 output:Next 13 号星期五是 13/4/2012

input:13 2 2003 输出:(我不得不关闭程序,因为它没有结束)

输入:22 4 1998 输出:(同上)

您可能想要调整 while 循环的条件。 以下情况您想继续添加一天:

  • 日期 mm/dd/yy 早于 m/d/y(尚未晚于给定日期)
  • 日期 mm/dd/yy 不是星期五 (day != 6)
  • 日期 mm/dd/yy 不是第 13 个 (dd != 13)

最后两个条件以正确的方式实现,但是如果日期在 "future" 中,您的检查将无法正常工作。 你可以试试这个:

yy < y || (yy == y && mm < m) || (yy == y && mm == m && dd <= d)

因此你需要的总条件是

yy < y || (yy == y && mm < m) || (yy == y && mm == m && dd <= d) || day != 6 || dd != 13

编辑 来解释为什么你 运行 进入一个无限循环 d >= 13:

您的条件有 dd <= ddd != 13。因此 dd 需要等于 13 并且大于(至少)13(提供的 d)才能使条件评估为假。这显然永远不会是这种情况,因此你会陷入无限循环。

实际原因是您的

while (dd <= d || mm <= m || yy <= y || day != 6 || dd != 13){

如果任何操作数为真,则为真,这是不正确的。想象一下 d > 13 时的情况。在这种情况下,当 dd 为 13 时,dd 将小于 d。但是 while 循环的条件只能是 false 如果 dd 是13. 因此,如果d > 13,则循环无限。另一个问题是,例如,如果 m 代表十二月,那么将识别任何更早月份的第 13 号星期五的 none none。

正确的算法如下:

d <- currentDate
found <- false
if day(d) <= 13 then
    currentDate <- findTheDateAt13th(currentDate)
    found <- isFriday(currentDate)
end if
while (not found) do
    currentDate <- findNextDateAt13th(currentDate)
    found <- isFriday(currentDate)
end while