遍历两个数组列表的问题
Issue iterating through two arraylists
编辑:非常感谢所有非常快速的反馈。哇。我只是为您粘贴了所有内容,而不仅仅是那两个 for 循环。谢谢
这可能之前已经完全回答过了。过去几年我读过 SO,但这是我的第一本 post。我一直在使用该网站和其他网站来帮助解决这个问题,所以如果有人回答这个问题,我提前表示歉意!
我正在遍历两个数组列表。一个来自用户输入;另一个是转换成数组列表的字典文件。我正在尝试将输入中的单词与字典中的单词进行比较。输入列表和字典列表是有效的,如果我简单地遍历它们,它们包含它们应该包含的内容(所以这不是问题。我认为我的问题在于我如何处理迭代。我是一个相当新手 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;
}
输入的输出结果"test tester asdasdfasdlfk"
[测试, 测试不匹配, 测试, 测试不匹配]
您应该将字典放入 HashSet 并 trim 添加所有单词。接下来你只需要循环输入列表并与 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();
trim 应该在将元素添加到列表时进行。 Trim 每次的字典值都是开销。内部循环本身也是如此。如果将字典数据结构从List改为Set,可以降低任务的复杂度。
将"fail"的结果移到外层循环的末尾。否则最后输入字符串的结果不会添加到结果列表中。
下面的代码很糟糕:
else {
fail = "No match for " + checker;
}
检查器不会在字典循环内更改。但是每次检查器和字典值不匹配时都会构造失败字符串。
看起来输入中的每个词都与字典中的每个词进行了比较。因此,对于每个不匹配的单词,您都会失败(尽管您只将字典中的最后一个失败写入结果)。问题似乎是即使在找到该词后您仍会继续循环。为避免这种情况,您可能希望将 break
添加到成功案例中:
if (checker.equals(currentWord)) {
match = currentWord;
results.add(currentWord);
fail = "";
break;
} else {
fail = "No match for " + checker;
}
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
来存储字典和 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;
}
我认为您的代码或多或少应该像下面这样。
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();
编辑:非常感谢所有非常快速的反馈。哇。我只是为您粘贴了所有内容,而不仅仅是那两个 for 循环。谢谢
这可能之前已经完全回答过了。过去几年我读过 SO,但这是我的第一本 post。我一直在使用该网站和其他网站来帮助解决这个问题,所以如果有人回答这个问题,我提前表示歉意!
我正在遍历两个数组列表。一个来自用户输入;另一个是转换成数组列表的字典文件。我正在尝试将输入中的单词与字典中的单词进行比较。输入列表和字典列表是有效的,如果我简单地遍历它们,它们包含它们应该包含的内容(所以这不是问题。我认为我的问题在于我如何处理迭代。我是一个相当新手 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;
}
输入的输出结果"test tester asdasdfasdlfk" [测试, 测试不匹配, 测试, 测试不匹配]
您应该将字典放入 HashSet 并 trim 添加所有单词。接下来你只需要循环输入列表并与 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();
trim 应该在将元素添加到列表时进行。 Trim 每次的字典值都是开销。内部循环本身也是如此。如果将字典数据结构从List改为Set,可以降低任务的复杂度。
将"fail"的结果移到外层循环的末尾。否则最后输入字符串的结果不会添加到结果列表中。
下面的代码很糟糕:
else {
fail = "No match for " + checker;
}
检查器不会在字典循环内更改。但是每次检查器和字典值不匹配时都会构造失败字符串。
看起来输入中的每个词都与字典中的每个词进行了比较。因此,对于每个不匹配的单词,您都会失败(尽管您只将字典中的最后一个失败写入结果)。问题似乎是即使在找到该词后您仍会继续循环。为避免这种情况,您可能希望将 break
添加到成功案例中:
if (checker.equals(currentWord)) {
match = currentWord;
results.add(currentWord);
fail = "";
break;
} else {
fail = "No match for " + checker;
}
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
来存储字典和 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;
}
我认为您的代码或多或少应该像下面这样。
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();