【问题标题】:HashCode loop not looping through string, program will not terminate due to while loopHashCode 循环没有遍历字符串,程序不会因为 while 循环而终止
【发布时间】:2023-03-24 12:43:01
【问题描述】:

我需要我的程序循环遍历 while 循环并询问用户无限数量的字符串...直到他们输入“完成”。如果他们埋葬的字符串不是“完成”,那么它会计算整个字符串的哈希码值并将其分类到适当的层中。用户输入完成后,程序会打印每一层的计数以及哪一层是最大的。

我的问题:程序要求用户输入一个字符串,计算每个字母的哈希值,将这些值排序到一个层中,打印计数,打印哪个层是最大的。然后向用户询问另一个字符串并继续此过程 -> 程序永远不会终止

仅供参考:我已将打印语句(在 for 循环之后)从 while 循环中取出,但出现编译错误:“找不到符号”指向我的所有“层”变量。我认为这意味着我需要在 while 循环 outside 声明它们,但如果我这样做了,则会出现同样的问题,因为它们没有在 while 循环 inside 循环中声明。

我需要程序做什么: 向用户询问一个字符串,计算哈希码,在适当的地方进行计数(进入适当的层)。继续这个循环,直到用户输入“完成”,然后程序打印每一层中的计数值,最后打印哪一层是最大的。

示例输出:

输入一个字符串:Foo
输入一个字符串:完成
大于或等于 2,000,000,000: 0
1,500,000,000 至 1,999,999,999:0
1,000,000,000 至 1,499,999,999:0
500,000,000 至 999,999,999:0
小于等于499,999,999:1
最大桶小于等于499,999,999,大小为1

**另外,我知道有一种更简单的方法可以确定哪一层最大(第 64-109 行),但我无法弄清楚。我们在课堂上没有讨论过数组或类似的东西,所以我不确定如何使用 if/else 语句来简化所有这些。**

import java.util.Scanner;
public class StringHashCodeLoop {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String strEntered;

// Prompt user for a string, store string in "strEntered."
System.out.println("Enter a String:");
strEntered = sc.next();

// Perform a while loop as long as the entered string does not equal "Done."
while (!strEntered.equals("Done")) {    
    // Convert all letters in the string to lower case.
    strEntered = strEntered.toLowerCase();

    // Declare the integer "length" and set it equal to the length of the entered string, to be used in the for loop.
    int length = strEntered.length();
    // Initialize each tier/bucket value to 0 before performing calculations.
    int tier1,tier2,tier3,tier4,tier5;
    tier1 = 0;
    tier2 = 0;
    tier3 = 0;
    tier4 = 0;
    tier5 = 0;

    for(int i = 0; i < length; ++i) {
        int hashValue = 0;
        hashValue += strEntered.charAt(i) * Math.pow(31, length - 1 - i);

        // Sort the Hash Code for the entered string into its corresponding bucket.
        if (hashValue >= 2000000000) {
            tier1++;
        }
        else if ((1500000000 < hashValue) && (hashValue < 1999999999)) {
            tier2++;
        }
        else if ((1000000000 < hashValue) && (hashValue < 1499999999)) {
            tier3++;
        }
        else if ((500000000 < hashValue) && (hashValue < 999999999)) {
            tier4++;
        }
        else {
            tier5++;
        }
    } // end of for loop

    System.out.println("Enter a String:");
    strEntered = sc.next();
} // end of while loop

// Print the tallied totals of each bucket.
System.out.println("Greater than 2,000,000,000: " + tier1);
System.out.println("1,500,000,000 to 1,999,999,999: " + tier2);
System.out.println("1,000,000,000 to 1,499,999,999: " + tier3);
System.out.println("500,000,000 to 999,999,999: " + tier4);
System.out.println("Less than or equal to 499,999,999: " + tier5);

// Print which is the largest bucket and the total of its contents.
    if (tier1 > tier2 && tier1 > tier3 && tier1 > tier4 && tier1 > tier5) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
    }
    else if (tier2 > tier1 && tier2 > tier3 && tier2 > tier4 && tier2 > tier5) {
        System.out.println("The largest bucket is 1,500,000,000 to 1,999,999,999 with a size of " + tier2);
    }
    else if (tier3 > tier1 && tier3 > tier2 && tier3 > tier4 && tier3 > tier5) {
        System.out.println("The largest bucket is 1,000,000,000 to 1,499,999,999 with a size of " + tier3);
    }
    else if (tier4 > tier1 && tier4 > tier2 && tier4 > tier3 && tier4 > tier5) {
        System.out.println("The largest bucket is 500,000,000 to 999,999,999 with a size of " + tier4);
    }
    else if (tier5 > tier1 && tier5 > tier2 && tier5 > tier3 && tier5 > tier4) {
        System.out.println("The largest bucket is Less than or equal to 499,999,999 with a size of " + tier5);
    }
    else if (tier1 == tier2) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
    }
    else if (tier1 == tier3) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
    }
    else if (tier1 == tier4) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
    }
    else if (tier1 == tier5) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
    }
    else if (tier2 == tier3) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier2);
    }
    else if (tier2 == tier4) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier2);
    }
    else if (tier2 == tier5) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier2);
    }
    else if (tier3 == tier4) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier3);
    }
    else if (tier3 == tier5) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier3);
    }
    else if (tier4 == tier5) {
        System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier4);
    }
}   
}

【问题讨论】:

  • 在while循环中移动第二行-> strEntered = sc.next();在while循环结束之前:即在}之前//while循环行结束,事情应该没问题
  • 顺便说一句,当您检查用户输入 Done 时,使用 equalsIgnorCase 而不是 equals。之前您使用 toLowerCase 将字符串从 Done 转换为 done,然后将其与 Done 进行比较。导致你的问题
  • @balajikrishnan 我更改了代码以解决您的第一条评论。我不知道你为什么建议我将第一个“输入字符串”提示放在循环中 - 如果用户尚未输入字符串,循环将如何检查字符串是否不等于“完成”?另外,我的作业说->“完成”一词(区分大小写)不应计入范围,并且区分大小写。尽管如此,您不应停止或忽略单词的变体,例如“dONE”、“DoNE”、“done”
  • @balajikrishnan ** 使用 equalsIgnoreCase 不会忽略这些变体并将它们计为字符串,而不是 while 循环的停用词吗?

标签: java for-loop while-loop hashcode


【解决方案1】:

移动线

int tier1,tier2,tier3,tier4,tier5;

到while循环之前,复制

tier1 = 0;
…
tier5 = 0;

并将其粘贴到您移动 int tier1… 行的位置之后(仍在 while 循环的上方/外部)。

这将消除编译器错误并让您的应用程序运行。

发生的情况是因为您在 while 和 if 语句中都使用了层变量,您需要在包含这两者的范围内声明变量。在 while 中声明它们意味着 只有 while 可以看到/使用它们。这就是为什么你必须把那段代码移出。

您必须复制这些初始化行(所有“tier# = 0”行)的原因是因为无论 while 是否完全运行(例如,如果用户将“完成”作为第一个输入)。但是,如果 while 循环从不运行,则 tier1 等将全部未初始化,并且 ifs 将失败。

这就是为什么你必须给它们一些初始值。在这种情况下,零可以正常工作。

您只复制该代码(将其留在 while 内)的原因是您仍然需要在每个循环中将这些值重置为零。

希望这是有道理且有帮助的。

【讨论】:

  • 你太棒了!非常感谢您的详细回复。 Java 语法和所有这些特殊规则(初始化等)让我感到困惑。非常感谢您的帮助!
【解决方案2】:

这应该可以完成工作:

import java.util.Scanner;
public class StringHashCodeLoop {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String strEntered;

// Prompt user for a string, store string in "strEntered."
System.out.println("Enter a String:");
strEntered = sc.next();

// Perform a while loop as long as the entered string does not equal "Done."
while (!strEntered.equals("Done")) {    
    // Convert all letters in the string to lower case.
    strEntered = strEntered.toLowerCase();

    // Declare the integer "length" and set it equal to the length of the entered string, to be used in the for loop.
    int length = strEntered.length();
    // Initialize each tier/bucket value to 0 before performing calculations.
    int tier1,tier2,tier3,tier4,tier5;
    tier1 = 0;
    tier2 = 0;
    tier3 = 0;
    tier4 = 0;
    tier5 = 0;

    for(int i = 0; i < length; ++i) {
        int hashValue = 0;
        hashValue += strEntered.charAt(i) * Math.pow(31, length - 1 - i);

        // Sort the Hash Code for the entered string into its corresponding bucket.
        if (hashValue >= 2000000000) {
            tier1++;
        }
        else if ((1500000000 < hashValue) && (hashValue < 1999999999)) {
            tier2++;
        }
        else if ((1000000000 < hashValue) && (hashValue < 1499999999)) {
            tier3++;
        }
        else if ((500000000 < hashValue) && (hashValue < 999999999)) {
            tier4++;
        }
        else {
            tier5++;
        }
    } // end of for loop

    System.out.println("Enter a String:");
    System.out.println("Greater than 2,000,000,000: " + tier1);
    System.out.println("1,500,000,000 to 1,999,999,999: " + tier2);
    System.out.println("1,000,000,000 to 1,499,999,999: " + tier3);
    System.out.println("500,000,000 to 999,999,999: " + tier4);
    System.out.println("Less than or equal to 499,999,999: " + tier5);

    // Print which is the largest bucket and the total of its contents.
        if (tier1 > tier2 && tier1 > tier3 && tier1 > tier4 && tier1 > tier5) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
        }
        else if (tier2 > tier1 && tier2 > tier3 && tier2 > tier4 && tier2 > tier5) {
            System.out.println("The largest bucket is 1,500,000,000 to 1,999,999,999 with a size of " + tier2);
        }
        else if (tier3 > tier1 && tier3 > tier2 && tier3 > tier4 && tier3 > tier5) {
            System.out.println("The largest bucket is 1,000,000,000 to 1,499,999,999 with a size of " + tier3);
        }
        else if (tier4 > tier1 && tier4 > tier2 && tier4 > tier3 && tier4 > tier5) {
            System.out.println("The largest bucket is 500,000,000 to 999,999,999 with a size of " + tier4);
        }
        else if (tier5 > tier1 && tier5 > tier2 && tier5 > tier3 && tier5 > tier4) {
            System.out.println("The largest bucket is Less than or equal to 499,999,999 with a size of " + tier5);
        }
        else if (tier1 == tier2) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
        }
        else if (tier1 == tier3) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
        }
        else if (tier1 == tier4) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
        }
        else if (tier1 == tier5) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier1);
        }
        else if (tier2 == tier3) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier2);
        }
        else if (tier2 == tier4) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier2);
        }
        else if (tier2 == tier5) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier2);
        }
        else if (tier3 == tier4) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier3);
        }
        else if (tier3 == tier5) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier3);
        }
        else if (tier4 == tier5) {
            System.out.println("The largest bucket is Greater than 2,000,000,000 with a size of " + tier4);
        }

    strEntered = sc.next();
} // end of while loop

// Print the tallied totals of each bucket.
}   
}

如果您只需要完成用户输入,则使用 equals 方法本身。

关于移动线路: 您最初所做的是使用 strEntered = sc.next(); 获取输入在while循环之前。检查输入 -> 等于完成然后继续。

在while循环内: 在扫描下一个输入后,它被转换为小写 -> 暗示在下一次迭代期间,它不可能在前面带有大写 D 的“完成”。这就是我要求将扫描部分移到 while 循环末尾的原因

【讨论】:

  • 这是我运行程序时的输出:输入一个字符串:嘘进入字符串:大于2,000,000,000:0 1,500,000,000至1,999,000,000至1,999,999,999,999:0 500,000,000至999,999,999:0大于或等于 499,999,999:3 最大的存储桶小于或等于 499,999,999,大小为 3 输入字符串:这使我回到我的“仅供参考”语句。如果我在打印所有计数之前结束循环,我会收到一条错误消息“无法找到符号”,指向我的所有“层”整数。
  • 我并不是要移动你的 while 循环的结尾。我刚刚说的移动 strEntered = sc.next();单独声明到循环结束,而不修改任何其他代码。这就是为什么我添加了我在这个答案中所说的代码。尝试运行我的代码,你不会得到找不到符号的错误。
  • 我完全复制并粘贴了您的代码,得到了如上所示的输出。在“最大的桶是...”行之后,它会提示用户再次输入一个字符串。这就是为什么我将 while 循环的结尾移到 println 语句上方的原因,这就是我得到编译错误“找不到符号”的原因。
猜你喜欢
  • 2016-06-21
  • 2019-06-25
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 2013-04-22
  • 2023-03-31
  • 1970-01-01
  • 2020-02-16
相关资源
最近更新 更多