【问题标题】:Iterate through a dictionary array遍历字典数组
【发布时间】:2018-01-29 20:56:01
【问题描述】:

我有一个字符串数组,其中包含一首故意拼写错误的诗。我试图通过将字符串数组与包含字典的字符串数组进行比较来遍历字符串数组以识别拼写错误。如果可能的话,我想要一个允许我继续使用嵌套 for 循环的建议

 for (int i = 0; i < poem2.length; i++) {
        boolean found = false;
        for (int j = 0; j < dictionary3.length; j++) {
            if (poem2[i].equals(dictionary3[j])) {
                found = true;
                break;
            }
        }
        if (found==false) {
            System.out.println(poem2[i]);
        }
    }

输出会打印出拼写正确的单词以及拼写错误的单词,我的目标是只打印出拼写错误的单词。以下是我填充“dictionary3”和“poem2”数组的方法:

      char[] buffer = null;
      try {
        BufferedReader br1 = new BufferedReader(new 
    java.io.FileReader(poem));
        int bufferLength = (int) (new File(poem).length());
        buffer = new char[bufferLength];
        br1.read(buffer, 0, bufferLength);
        br1.close();
    } catch (IOException e) {
        System.out.println(e.toString());
    }

    String text = new String(buffer);
    String[] poem2 = text.split("\\s+");

    char[] buffer2 = null;
    try {
        BufferedReader br2 = new BufferedReader(new java.io.FileReader(dictionary));
        int bufferLength = (int) (new File(dictionary).length());
        buffer2 = new char[bufferLength];
        br2.read(buffer2, 0, bufferLength);
        br2.close();
    } catch (IOException e) {
        System.out.println(e.toString());
    }

    String dictionary2 = new String(buffer);
    String[] dictionary3 = dictionary2.split("\n");

【问题讨论】:

  • 我复制了您的代码并尝试了数组String[] poem2 = new String[]{"test", "asdf"};String[] dictionary3 = new String[]{"apple", "banana", "test"};,并且只正确收到了值asdf。也许你的字典有问题?
  • 我无法重现您的问题。它只为我打印不正确的单词ideone.com/TghyDx
  • 但这就是您的代码所做的与您在“输出打印出正确拼写的单词以及拼写错误的单词”中所声称的相反。如果您在正确的minimal reproducible example(又名SSCCE)后没有得到预期的结果。此外,“我的字典是一个 txt 文件”并没有告诉我们太多,因为 dictionary3 看起来不像 File 实例,而是像 String[] 数组。您可能声称该数组应该填充文本文件的内容,但它不是文本文件,也不是有关其位置的信息。
  • @Keara 我已经编辑了我的帖子,代码显示了我在哪里初始化我的 dictionary3 和poem2 变量
  • @Pshemo 我编辑的帖子是否为您提供了更多说明?抱歉,不清楚。

标签: java arrays string loops nested-loops


【解决方案1】:

你的基本问题在排队

String dictionary2 = new String(buffer);

您试图转换表示存储在buffer2 中的字典的字符,但您使用了buffer(没有2 后缀)。这种命名变量的风格可能表明您需要一个循环,或者在这种情况下需要一个单独的方法,该方法将返回它所包含的选定文件数组(您也可以添加作为方法参数分隔符应该拆分哪个字符串)。

所以你的dictionary2 包含来自buffer 的字符,它们代表诗歌,而不是字典数据。

另一个问题是

String[] dictionary3 = dictionary2.split("\n");

因为您只在 \n 上拆分,但某些操作系统(如 Windows)使用 \r\n 作为行分隔符序列。所以你的字典数组可能包含像foo\r 这样的词而不是foo 这将导致poem2[i].equals(dictionary3[j] 总是失败。

为避免此问题,您可以拆分\\R(Java 8 起可用)或\r?\n|\r


您的代码中还有其他问题,例如在 try 部分中关闭资源。如果之前抛出任何异常,close() 将永远不会被调用而留下未关闭的资源。要解决它,请关闭 finally 部分中的资源(始终在尝试后执行 - 无论是否抛出异常),或者更好地使用 try-with-resources


顺便说一句,您可以简化/澄清负责从文件中读取单词的代码

List<String> poem2 = new ArrayList<>();
Scanner scanner = new Scanner(new File(yourFileLocation));
while(scanner.hasNext()){//has more words
    poem2.add(scanner.next());
}

对于字典而不是List,您应该使用Set/HashSet 以避免重复(通常集合在检查它们是否包含某些元素时也具有更好的性能)。这样的集合已经提供了像contains(element) 这样的方法,所以你不需要那个内部循环。

【讨论】:

    【解决方案2】:

    我复制了您的代码并运行了它,但发现了两个问题。好消息是,两者都是非常快速的解决方法。

    #1 当我将dictionary3 中的所有内容读入后打印出来时,它与poem2 中的所有内容完全相同。您在字典中阅读的代码中的这一行是问题所在:

     String dictionary2 = new String(buffer);
    

    您正在使用buffer,这是您在诗歌中读到的变量。因此,缓冲区包含这首诗,你的诗和字典最终是一样的。我想你想改用buffer2,这是你以前在字典里读到的:

     String dictionary2 = new String(buffer2);
    

    当我改变它时,字典和诗歌似乎有正确的条目。

    #2 另一个问题,正如 Pshemo 在他们的回答中指出的那样(这是完全正确的,而且是一个非常好的答案!)是你正在为字典拆分 \n。在这里我要说的与 Pshemo 唯一不同的是,您可能应该像为这首诗所做的那样在 \\s+ 上进行拆分,以保持一致。其实我在调试的时候发现字典里的单词都在末尾加了“\r”,可能是因为你在\n上分裂了。要解决此问题,请更改此行:

    String[] dictionary3 = dictionary2.split("\n");
    

    到这里:

    String[] dictionary3 = dictionary2.split("\\s+");
    

    尝试更改这两行,如果这样可以解决您的问题,请告诉我们。祝你好运!

    【讨论】:

    • 耶!!我很高兴。如果这个答案有帮助,请考虑接受它,以便其他用户可以轻松找到它。
    【解决方案3】:

    将您的字典转换为 ArrayList 并改用 Contains

    这样的事情应该可以工作:

    if(dictionary3.contains(poem2[i])
       found = true;
    else
       found = false;
    

    使用此方法,您还可以摆脱嵌套循环,因为 contains 方法会为您处理。

    您可以使用以下方法将您的 Dictionary 转换为 ArrayList: new ArrayList&lt;&gt;(Arrays.asList(array))

    【讨论】:

    • 无论什么原因我都不能使用 contains
    • 他们什么时候拿出来的? docs.oracle.com/javase/7/docs/api/java/util/…
    • @BrandonMiller OP 要求提供数组,您在 length 而不是 length() 中看到的内容
    • 您不需要使用ArrayList。任何类型的List 都可以——包括Arrays.asList() 返回的类型,因此无需通过复制整个列表来耗尽不必要的内存。此外,您甚至不需要List;只需使用Arrays.contains()
    • 您的原始代码应该可以工作,除了您的字符串比较区分大小写这一事实。尝试使用 String.equalsIgnoreCase() 而不是 .equals()... 您可能还想在比较之前修剪()您的诗歌字符串和字典字符串。当您比较字符串时,它们必须完全匹配才能相等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    • 2014-07-31
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    • 2015-05-19
    • 1970-01-01
    相关资源
    最近更新 更多