编辑:非常感谢所有非常快速的反馈。哇。我把它全部粘贴给你,而不仅仅是那两个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”的输出结果 [测试,测试不匹配,测试仪,测试仪不匹配]
答案 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;
}
检查器在字典循环中不会更改。但是每次检查器和字典值不匹配时都会构造失败字符串。