遍历字典数组

Iterate through a dictionary array

我有一个字符串数组,其中包含一首故意拼写错误的诗。我试图遍历字符串数组,通过将字符串数组与包含字典的字符串数组进行比较来识别拼写错误。如果可能的话,我想要一个允许我继续使用嵌套 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");

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

像这样的东西应该可以工作:

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

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

您可以使用以下方法将 Dictionary 转换为 ArrayList: new ArrayList<>(Arrays.asList(array))

我复制了您的代码并 运行 它,我注意到两个问题。好消息是,两者都是非常快速的修复。

#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+");

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

你的基本问题符合

String dictionary2 = new String(buffer);

您尝试转换表示存储在 buffer2 中的字典的字符,但您使用了 buffer(没有 2 后缀)。这种命名变量的方式可能表明您需要一个循环,或者在这种情况下,单独的方法将 return 用于它包含的选定文件数组的单词(您还可以添加作为方法参数定界符的字符串应该是分裂)。

所以你的 dictionary2 保存了 buffer 中代表诗歌的字符,而不是字典数据。

另一个问题是

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

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

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


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


顺便说一句,您可以 simplify/clarify 您负责从文件中读取单词的代码

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) 这样的方法,所以你不需要那个内部循环。