如何统计字符数组中每个字符的出现次数?

3
我正在尝试计算字符数组中每个字符的出现次数。特定的小写或大写字母出现了多少次?我一直在循环并遇到错误,有什么有效的方法吗?
这是我用来填充随机字符数组的代码:
char[] chararray = new char[1000]; 
   for (int i = 0; i < chararray.length; i++) { 
       char c = randomCharacter();
       chararray[i] = c;  
   }//end for  

我尝试创建第二个数组来计算大写和小写字母,但是我不确定该怎么做:

int[] counter = new int[52];

非常感谢您的帮助。谢谢。


1
你只关心特定范围的字符吗(例如英文字母)? - Bobby StJacques
1
你需要查看Java Map类:http://docs.oracle.com/javase/7/docs/api/java/util/Map.html - The Coding Monk
2
不用Map,字符是整数,使用数组更高效。 - Bobby StJacques
1
你熟悉ASCII吗?如果你只关心这52个字符,并且保证输入中只有这些字符,那么你可以循环遍历它们并将它们添加到你创建的int[] counter = new int[52]数组中。如果它们不在该范围内,你可以先检查它们是否在你感兴趣的字符之间,然后减去它们以获取索引。ASCII值'A'=65,'Z'=90和'a'=97,'z'=122。 - mkobit
嘿,感谢回复。我只关心字符'a'-'z'和'A'-'Z',但是我将它们连在一起计算,没有间隔。ASCII方法听起来也很有效,稍后会尝试一下。谢谢。 - KingKrypton
即使提问者添加了对A-Za-z的检查,这些值仍然是UTF-16代码单元(尽管在此范围内,只需要一个代码单元来表示一个代码点)。它们也属于ASCII字符集,并且在ASCII编码中具有相同的编码值,但这并不相关。 - Tom Blodget
6个回答

2

这里有一个相对简单的方法,使用Java 8流

Character[] charArray = new Character[1000];
IntStream.rand(0, charArray.length)
    .forEach(n -> charArray[n] = randomCharacter());
Map<Character, Long> charCountMap = Arrays.stream(charArray)
    .collect(Collectors.groupingBy(Function.identity(), Collectors.counting());

这将为您提供每个字符在数组中出现次数的映射。

除非您每秒处理数十亿个字符或尝试在90年代的数字手表上运行它,否则不必考虑效率。


@ShivaShinde 谁在乎呢?这是一个由1000个字符组成的数组。OP明确要求“有效”。 - sprinter
1
@ZongZhengLi 真的吗?你能再解释一下吗?我认为这正是 OP 想要的。 - sprinter
1
我相信你意识到这对于初学者来说是毫无用处的。这里唯一的目标应该是帮助初学者理解解决方案,而不是把它当作代码高尔夫练习。你不能说你真的打算通过这个答案来帮助 OP。 - Zong
@ZongZhengLi 在我看来,学习API也是学习过程的一部分。 - Puce
1
@ZongZhengLi 我真的是想帮助他们的。我的经验是,新学生从一开始就学习函数式编程,掌握流和传统迭代一样容易。 - sprinter
显示剩余6条评论

1
假设您只关心英文字母字符。在Java中,char类型实际上是一个整数,因此您可以使用for循环来循环范围,例如:
for( char c='a'; c<='z'; c++) {
   for( char x : chararry ) {
        if( c == x ) {
           // increment your counter for 'c'
        }
   }
}

使用类似的循环来处理大写字符。
现在问题只是要将计数器存储在哪里。我建议使用一个数组,其中每个索引对应于您的字符值之一。您可以编写一个非常简单的方法,将ASCII字符值转换为0-51范围内的索引。

1
嗯,是的,你可以那样做,但它非常低效--当你可以用O(n)完成时,它是O(n^2)。最好只需遍历一次数组,并直接从每个char计算要增加的计数器的索引(如果有)。 - John Bollinger
1
@JohnBollinger 这不是O(n^2),因为字母表的大小不随问题规模增加而增加。即使有两个循环,它仍然是O(n)或O(nk),其中k是字母表的大小。 - Zong
1
是的,没错。只是针对一个小问题提出了一个简单、直观的暴力解决方案。(O(2nk)) - Bobby StJacques
@ZongZhengLi,你说得很对。我一离开电脑就后悔说了那句话。我知道会有人指出我的错误。尽管如此,性能恶化26倍(或更多,取决于计算哪些字符)是完全不够好的。 - John Bollinger

0
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class CountOccurencesOfLetters {

    public static void main(String[] args) 
    {
        String s=" abhiabhiabhiabhiabhi";
        countOcccurence(s);
    }
    private static void countOcccurence(String input)
    {
        Map<String, Integer> map = new HashMap<String, Integer>();
        String[] tokens =input.split("");
        for (int i = 0; i < tokens.length; i++) 
        {
            String string = tokens[i];
            if(map.containsKey(string))
            {
                int value=map.get(string);
                value++;
                map.put(string, value);
            }
            else
            {
                map.put(string, 1);
            }
        }
        Set<Entry<String,Integer>> entryset = map.entrySet();
        for(Entry<String,Integer> entry: entryset)
        {
            System.out.print(entry.getKey()+entry.getValue());
        }
    }
}

0

有很多方法可以获得所需的结果。以下是一种方法,请尝试 ----

package com.test;

import java.util.HashMap;
import java.util.Map;

public class CharCountInArray {

public static void main(String[] args) {
    char[] arr ;
    arr = new char[]{'a', 'b', 'c', 'a', 'b', 'c', 'd','a', 'b', 'c', 'a', 'b', 'c', 'd','a', 'b', 'c', 'a', 'b', 'c', 'd','a', 'b', 'c', 'a', 'b', 'c', 'd','a', 'b', 'c', 'a', 'b', 'c', 'd'};

    Map<Character, Integer> m = new HashMap<Character, Integer>();

    for(int i = 0; i< arr.length; i++){

        if(m.containsKey(arr[i])){

            m.put(arr[i], m.get(arr[i]) + 1);
        }
        else {
            m.put(arr[i], 1);
        }
    }
    System.out.println(m);
}
}

这是输出 -- {a=10, b=10, c=10, d=5} - Arvind Kumar

0
public void count(char[] chararray) {
    Map<Character, Integer> map = new HashMap<>();
    for (Character character : chararray) {
        Integer characterCount = map.get(character);
        if(characterCount == null) {
            characterCount = 0;
        }
        characterCount++;
        map.put(character, characterCount);
    }
    System.out.println(map);
}

-1
public class Array_Test {

public static void main(String[] args) {
   char[] c={'a','$','a','f','f','$','d','a','6','f','6','e','r','e','#','y','y','#','a','g','r','g'};
   int char_counter=0;      
   char [] c_distinct=new char[c.length];    
   boolean contains=false;
   int index_counter=0;

      for( int i=0;i<=c.length-1;i++)
      {
          if(i==0)
          {
          c_distinct[index_counter]=c[0];
          index_counter++;
          }
          else
          {
          contains=false;
          for(int k=0;k<=c.length-1;k++)
          {
              for(int f=0;f<=index_counter;f++)
              {
                  if(c_distinct[f]==c[i])
                  contains=true;    
              }                  
          }
          if(contains==false)
          {
              c_distinct[index_counter]=c[i];
              index_counter++;                  
          }
          }
      }

      System.out.println(c);
      System.out.println(c_distinct);

      for(int a=0;a<=index_counter-1;a++)
      {
          char_counter=0;
          for(int b=0;b<=c.length-1;b++)
          {

              if(c_distinct[a]==c[b])
              {
                  char_counter++;
              }
          }
          System.out.println(c_distinct[a]+" "+char_counter);
      }                     
   }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接