问题迭代两个arraylists

时间:2015-07-21 23:00:00

标签: java arraylist iteration

编辑:非常感谢所有非常快速的反馈。哇。我把它全部粘贴给你,而不仅仅是那两个for循环。感谢。

之前可能已经完全回答过了。我在过去的几年里读过SO,但这是我的第一篇文章。我一直在使用该网站和其他人来帮助解决这个问题,所以如果这个问题得到解答我会提前道歉!

我正在迭代两个arraylists。一个来自用户输入;另一个是转换成arraylist的字典文件。我试图将输入中的单词与字典单词进行比较。输入列表和字典列表是有效的,如果我只是遍历它们,它们包含它们应该的东西(所以这不是问题。我认为我的问题在于我如何处理迭代。我是公平的新手Java程序员,所以请放轻松我。

由于

    public String isSub(String x) throws FileNotFoundException, IOException  {
    //todo handle X
    String out = "**********\nFor input \n" + x + "If you're reading this no match was found.\n**********";
    String dictionary;


    boolean solve = true;

    /// Get dictionary
    dictMaker newDict = new dictMaker();
    dictionary = newDict.arrayMaker();

    List<String> myDict = new ArrayList<String>(Arrays.asList(dictionary.split(",")));
    List<String> input = new ArrayList<String>(Arrays.asList(x.split(" ")));
    List<String> results = new ArrayList<String>();
    //results = input;

    String currentWord;
    String match = "";
    String checker = "";
    String fail="";


    //Everything to break sub needs to happen here.
    while (solve) {


     for(int n = 0; n < input.size(); n++) { //outside FOR (INPUT)
       if(!fail.equals("")) results.add(fail);
       checker = input.get(n).trim();
       for(int i = 0; i < myDict.size(); i++) { //inside FOR (dictionary)
        currentWord = myDict.get(i).trim();
        System.out.print(checker + " " + currentWord + "\n");
        if(checker.equals(currentWord)) {

                match = currentWord;
                results.add(currentWord);
                fail="";

            } //end if
            else {

                fail = "No match for " + checker;

            }

          }//end inside FOR (dictionary)

        }   //END OUTSIDE FOR (input)

        solve=false;

     } //end while


        out = results.toString();

        return out;
}

输入“测试测试仪asdasdfasdlfk”的输出结果 [测试,测试不匹配,测试仪,测试仪不匹配]

4 个答案:

答案 0 :(得分:1)

看起来输入中的每个单词都与词典中的每个单词进行比较。因此,对于每个不匹配的单词,您会收到失败(尽管您只将字典中的最后一个失败写入结果)。问题似乎是,即使找到了这个单词,你仍然会继续循环。为避免这种情况,您可能希望将break添加到成功案例中:

if (checker.equals(currentWord)) {
    match = currentWord;
    results.add(currentWord);
    fail = "";
    break;
} else {
    fail = "No match for " + checker;
}

答案 1 :(得分:1)

Carl Manaster给出了正确的解释。

以下是您的代码的改进版本:

for (int n = 0; n < input.size(); n++) { //outside FOR (INPUT)
    String checker = input.get(n).trim();
    boolean match = false;
    for (int i = 0; i < myDict.size(); i++) { //inside FOR (dictionary)
        String currentWord = myDict.get(i).trim();
        System.out.print(checker + " " + currentWord + "\n");
        if (checker.equals(currentWord)) {
            match = true;
            results.add(currentWord);
            break;
        } //end if
    } //end inside FOR (dictionary)
    if (!match) {
        results.add("No match for " + checker);
    }
} //END OUTSIDE FOR (input)

此外,请考虑使用HashMap代替ArrayList来存储字典,并在存储字词时对其进行修剪以避免在每次传递中执行此操作。

答案 2 :(得分:0)

如果您使用字典,则应使用不带索引的键来获取字典。所以它应该是

                if(myDict.containsKey(checker)){
                    String currentWord =myDict.get(checker);
                    System.out.print(checker + " " + currentWord + "\n");
                    match = currentWord;
                    results.add(currentWord);
                    fail = "";
                }
                else {
                    fail = "No match for " + checker;
                }

我认为您的代码或多或少应该遵循。

ArrayList<String> input= new ArrayList<String>();
      input.add("ahmet");
      input.add("mehmet");
      ArrayList<String> results= new ArrayList<String>();
      Map<String, String> myDict = new HashMap<String, String>();
      myDict.put("key", "ahmet");
      myDict.put("key2", "mehmet");
      String match="";
      String fail="";
    for (int n = 0; n < input.size(); n++) { //outside FOR (INPUT)
            if (!fail.equals("")) 
                results.add(fail);
            String checker = input.get(n).trim();

            for (int i = 0; i < myDict.size(); i++) { //inside FOR (dictionary)

             //   String currentWord = myDict.get(i).trim();
                if(myDict.containsKey(checker)){
                    String currentWord =myDict.get(checker);
                    System.out.print(checker + " " + currentWord + "\n");
                    match = currentWord;
                    results.add(currentWord);
                    fail = "";
                }
                else {
                    fail = "No match for " + checker;
                }
            } // end inside FOR (dictionary)
        }   // end outside FOR (input)

     //   solve = false; I dont know what is this

    //} //end while. no while in my code

    return results.toString();

答案 3 :(得分:-1)

您应该将字典放入HashSet并修剪,同时添加所有单词。接下来,您只需循环输入列表并与dict.conatins(inputWord)进行比较。这节省了为所有输入单词处理的可能的大字典循环。

未经测试的脑转储:

HashSet<String> dictionary = readDictionaryFiles(...);
List<String> input = getInput();

for (String inputString : input)
{
     if (dictionary.contains(inputString.trim()))
     {
          result.add(inputString);
     }
}

out = result.toString()
....

和原始帖子类似的解决方案。删除了不必要的循环索引变量:

    for (String checker : input)
    { // outside FOR (INPUT)
        fail = "No match for " + checker;
        for (String currentWord : myDict)
        { // inside FOR (dictionary)
            System.out.print(checker + " " + currentWord + "\n");
            if (checker.equals(currentWord))
            {
                match = currentWord;
                results.add(currentWord);
                fail = null;
                break;
            }
        } // end inside FOR (dictionary)
        if (fail != null)
        {
            results.add(fail);
        }
    } // end outside FOR (input)

    solve = false;

    return results.toString();

在将元素添加到列表时应进行修剪。每次开销时修剪字典值。而内循环本身也是如此。如果将字典数据结构从List更改为Set,则可以减少任务的复杂性。

添加“失败”的结果将移动到外部循环的末尾。否则,最后一个输入字符串的结果不会添加到结果列表中。

以下代码非常糟糕:

else {
    fail = "No match for " + checker;
}

检查器在字典循环中不会更改。但是每次检查器和字典值不匹配时都会构造失败字符串。