【问题标题】:For loop confusion, why isn't this looping?对于循环混淆,为什么不循环?
【发布时间】:2016-10-17 18:48:31
【问题描述】:

所以我有一个方法,我将一个 ArrayList 传递给该方法的想法是获取输入并将每组匹配的字符串拆分为它们自己的单独列表。这里有一些伪代码。

Array = (a,a,a,b,c,d,d,e,e,e,e,e,f,f,s)

所以我想要这个算法做的是把这个数组分割成一个元素相等的二维数组。像这样。

A[0][] = (a,a,a)
A[1][] = (b)
A[2][] = (c)
A[3][] = (d,d)
A[4][] = (e,e,e,e,e)
A[5][] = (f,f)
A[6][] = (s)

所以我试图做的是把它放在一个 for 循环中,在前面检查一个额外的元素,看看它是否不等于,然后它就知道了

 int equalStringGroupIndex = 0;
    int i = 0;

    for(int first = 0, second = 0 ; input.get(first).equals(input.get(second)); second++){
        equalStringGroups[equalStringGroupIndex][i] = input.get(second);
        i++;
        //This if statment checks the element ahead then equals first = second, But when it jumps back to the top of the loop in the debugger it does'nt seem to check it even though in my Watches it's True
        if(!input.get(first).equals(input.get(second + 1))){
            equalStringGroupIndex++;
            i = 0;
            first = second;
        }
    }

为什么将第一组'a'添加到二维数组后它不循环 谢谢。

更新: 感谢您的帮助,我决定走 HashMap 路线。这就是我想出的。它似乎可以工作。

private HashMap<String, Integer> countDuplicates(ArrayList<String> input){

    HashMap<String, Integer> duplicates = new HashMap<>();

    //Value init loop, sets all values to 0;
    for (String s : input){
        Integer valueInitVar = 0;
        duplicates.put(s, valueInitVar);
    }

    //Increases the value by 1  each time the same key is encountered;
    for (String s : input){
        Integer tempDuplicateAmount = duplicates.get(s);
        //I could use the '++' operator but I feel ' var += 1' is much nicer to read;
        tempDuplicateAmount += 1;
        duplicates.put(s, tempDuplicateAmount);
    }

    return duplicates;
}

【问题讨论】:

  • 已排序的字符串数组
  • 为什么会发生what
  • 将第一组'a'添加到二维数组后不循环
  • 那是因为你的条件是假的。 a 不等于 b,所以它退出了。您应该使用input.lengthinput.size 作为条件并进行相应的测试
  • 这是作业吗?存储相同字符串的数组并没有什么意义。为什么不只存储一个映射,其中键是不同的字符串,值是一个整数,表示它出现了多少次。这段代码过于复杂,但即使是简化版本也会比使用地图更复杂。此外,您的输入无需进行排序即可工作。

标签: java for-loop


【解决方案1】:

我建议别的:

List<List<Whatever>> splitSame(List<Whatever> input) {
  List<List<Whatever>> rv = new ArrayList<>();
  List<Whatever> currentValues = new ArrayList<>(); 
  Whatever lastChecked = input.get(0);
  for (Whatever what : input) {
    if (lastChecked.equals(what)) {
      currentValues.add(what);
    } else {
      rv.put(currentValues);
      currentValues = new ArrayList<>();
    }
    lastChecked = what;
  }
  rv.put(currentValues);
  return rv;

重点是:您可以轻松地遍历一个输入列表以在子列表中收集相等的对象。最后,您只需将它们组合在一起即可。

我确信一些 java8 大师可以使用流将上面的内容重写为更简洁和不那么复杂的东西。

这里根本不需要额外的二维数组复杂性!

( 提示:刚刚写下的代码,可能包含拼写错误,并且当 last 元素不同时,其中存在一个细微的错误,但是:它旨在让您了解如何做事情不同;更多细节留给读者)

【讨论】:

  • 绝对是更好的方法。
  • @MichaelPickett 在哪里,我不得不承认,List 和 ListList 看起来有点吓人;使整个事情比实际更难阅读。可能这确实是一些流魔术真正吹嘘“老派”的案例之一。
  • 我不觉得这很可怕,但如果您从“老派”的角度来看,它可能会有点压倒性。通读一遍就很容易理解了。
【解决方案2】:

如果您要坚持这样做,我建议您将 for 循环中的条件更改为 second &lt; input.size (or length)

int equalStringGroupIndex = 0;
int i = 0;

for(int first = 0, second = 0 ; second < input.size(); second++){
    equalStringGroups[equalStringGroupIndex][i] = input.get(second);
    i++;

    if(!input.get(first).equals(input.get(second + 1))){
        equalStringGroupIndex++;
        i = 0;
        first = second+1;
    }
}

这样,您只在数组中循环,没有超出范围的异常。

我还将您的first = second 更改为first = second+1,因为一旦您发现它们不相等,您应该将第一个索引设置为下一个索引,而first = second 则不是。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-02
    • 1970-01-01
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 2013-09-24
    • 2018-12-16
    • 1970-01-01
    相关资源
    最近更新 更多