在Arraylist中计算重复和分组

时间:2015-02-04 03:45:34

标签: java string arraylist

对于我的项目,我们必须使用Java操纵某些LISP措辞。其中一项任务是:

'(A A A A B C C A A D E E E E)

将重复项分组并输出如下:

′((4A)(1B)(2C)(2A)(1D)(4E))

注意前四个A与前两个A分开的方式......

我的问题在于跟踪每个字母的数量。我将给定的字母添加到数组列表中,然后我稍微操作了一下:

for (int i=0;i<list.size();i++)
    {
        String val=list.get(i);
        String first=list.get(0);
        while (val.equals(first))
        {
            total+=1;
            val="X";
        }
    }

总数应该是第一次出现的次数,但是它一直给我6. 6是序列中所有A的正确数字,但是如何让它在前四次停止,记下数字并继续下一封信?

5 个答案:

答案 0 :(得分:1)

这是Java 8 Stream API。

 Map<Character, Long> countedDup =  Arrays.asList('A' ,'A' ,'A', 'A', 'B', 'C', 'C', 'A', 'A', 'D', 'E', 'E', 'E', 'E')
        .stream().collect(Collectors.groupingBy(c -> c, Collectors.counting()));
            System.out.println(countedDup);//{A=6, B=1, C=2, D=1, E=4}

答案 1 :(得分:0)

这是我的解决方案:

    for (int i = 0; i < list.size(); i++) {
        String first = list.get(i);
        int total = 1;
        while (i + 1 < list.size() && first.equals(list.get(i + 1))) {
            total++;
            i++;
        }
        System.out.println("(" + total + first + ")");
    }

您可以调试以了解它的运行方式。

*****请注意,比较2个String对象时,请勿使用==。使用方法equals()

答案 2 :(得分:0)

为了获得您在问题中指定的所需输出,我将跟踪给定列表中的当前值和下一个值。元素计数从1开始,当相等条件为真时递增,否则重置为1.最后输出仅在相等条件为假时更新。

示例代码:

编辑我根据@Ascalonian的建议更新了我的代码。

String inputString = "'(A A A A B C C A A D E E E E)";

// I assume that the input always starts with "'("
String finalOutput = inputString.substring(0, 2);
int valCount = 1;

String valCurrent = inputString.substring(2, 3);
String valNext = "";

for (int i = 4; i < inputString.length(); i++) {

    valNext = inputString.substring(i, i + 1);
    if (valNext.equals(" ")) {
        continue;
    }

    if (valCurrent.equals(valNext)) {
        valCount++;
    } else {
        finalOutput += "(" + valCount + valCurrent + ")";
        valCount = 1;
    }
    valCurrent = valNext;
}

finalOutput += ")";

System.out.println(finalOutput);
  

输出字符串:'((4A)(1B)(2C)(2A)(1D)(4E))

我希望这会有所帮助。

答案 3 :(得分:0)

这是我的解决方案,虽然没有使用arrayList:

根据 Ascalonian 指出

编辑

String text = "'(A A V A B C C X X X X A A Z Z Z K L N N N N N)";
int counter = 1;
System.out.print("'(");
for (int i = 2; i < text.length() - 1; i = i + 2) {
    System.out.print("(");
    while (((i + 2) < text.length())
        && (text.charAt(i) == text.charAt(i + 2))) {
    ++counter;
    i += 2;
    }
    System.out.print(counter + "" + text.charAt(i) + ")");
    counter = 1;
}
System.out.print(")");

o / p将用于示例文本:

  

((2A)(1V)(1A)(1B)(2C)(4X)(2A)(3Z)(1K)(1L)(5N))

答案 4 :(得分:0)

不确定是否需要使用ArrayList,但如果没有,我会使用不同的方法,只获取字母,去除空格,使其为char[]并迭代每个信件。

// the initial LISP phrase
String lispPhrase = "'(A A A A B C C A A D E E E E)";

// Pull out just the letters
String letters = lispPhrase.substring(2, lispPhrase.length()-1);

// Remove the white space between them
letters = letters.replaceAll("\\s","");

// Get an array for each letter
char[] letterArray = letters.toCharArray();

char previousLetter = ' ';
char nextLetter = ' ';
int letterCounter = 1;

System.out.print("'(");

// now go through each letter
for (char currentLetter : letterArray) {
    // If the first time through, set previousLetter
    if (previousLetter == ' ') {
        previousLetter = currentLetter;
    }else {
        nextLetter = currentLetter;

        // Is the next letter the same as before?
        if (previousLetter == nextLetter) {
            letterCounter++;
        }else {
            // If the next letter is different, print out the previous letter and count
            System.out.print("(" + letterCounter + previousLetter + ")");

            // Reset the counter back to 1
            letterCounter = 1;
        }

        previousLetter = nextLetter;
    }
}

System.out.print("(" + letterCounter + previousLetter + "))");  

这给出了输出:

  

“((4A)(1B)(2C)(2A)(1D)(4E))