【问题标题】:Count the occurrence of every alphabet from a string计算字符串中每个字母的出现次数
【发布时间】:2016-01-23 13:41:45
【问题描述】:

我知道这个主题之前已经介绍过,但我没有找到我需要的内容。我正在尝试计算字母表中每个字母的出现次数;来自用户输入的字符串。输出将包括所有 26 个字母,即使它们没有出现。因此,0 将分配给未出现的字母。我通过循环遍历一组字母并将其与用户输入进行比较来做到这一点。

我在添加字母和显示每个字母时遇到问题。我的输出结果显示输入的每个字母 + 1。

    public class TwoArrays {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        char[] lower = new char[] {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
        char[] upper = new char[] {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

        System.out.println("Please enter a sentence to parse.");
        String userString = input.nextLine();

        for(int i = 0; i < userString.length(); i++) {
            //lowercase
            for(int l = 0; l < lower.length; l++) {
                int counter = 0;
                if(lower[l] == userString.charAt(i)) {
                    counter++;
                    System.out.println(lower[l] + ":" + counter);
                }
            }   
            //uppercase
            for(int u = 0; u < upper.length; u++) {
                int counter = 0;
                if(upper[u] == userString.charAt(i)) {
                    counter++;
                    System.out.println(upper[u] + ":" + counter);
                }
            }
        }
    }
}

输出

Please enter a sentence to parse.
hello WORLD
h:1
e:1
l:1
l:1
o:1
W:1
O:1
R:1
L:1
D:1

【问题讨论】:

  • 需要区分oO吗?
  • 我是 Java 和一般编程新手,所以我不熟悉哈希图和高级 API。我会阅读它们并尝试理解所有答案的含义。谢谢大家!

标签: java arrays string loops char


【解决方案1】:

使用增强循环 + HashMap,您可以统一两个包含字符的数组:

public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
    char[] array = new char[] {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
            'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

    System.out.println("Please enter a sentence to parse.");
    String userString = input.nextLine();

    HashMap<Character, Integer> charint = new HashMap<>();

    for (Character c : userString.toCharArray()){
        if (charint.containsKey(c)) charint.replace(c, charint.get(c).intValue() + 1);
        else charint.put(c, 1);
    }

    for (int i = 0 ; i < array.length ; i++){
        System.out.println(array[i] + " : " + (charint.get(array[i]) == null ? "0" : charint.get(array[i])));
    }
}

输出

Please enter a sentence to parse.
Hello the world
a : 0
b : 0
c : 0
d : 1
e : 2
f : 0
g : 0
h : 1
i : 0
j : 0
k : 0
l : 3
m : 0
n : 0
o : 2
p : 0
q : 0
r : 1
s : 0
t : 1
u : 0
v : 0
w : 1
x : 0
y : 0
z : 0
A : 0
B : 0
C : 0
D : 0
E : 0
F : 0
G : 0
H : 1
I : 0
J : 0
K : 0
L : 0
M : 0
N : 0
O : 0
P : 0
Q : 0
R : 0
S : 0
T : 0
U : 0
V : 0
W : 0
X : 0
Y : 0
Z : 0

【讨论】:

    【解决方案2】:

    这是一种使用hashmap 的方法。既然要显示0char不在字符串中,我们可以先putmap中的所有字符。然后我们可以遍历字符串并增加找到的字符的value

    Map<Character, Integer> charMap = new HashMap<Character, Integer>();
    
    for (Character c: "abcdefghijklmnopqrstuvwxyz".toCharArray()) {
        charMap.put(c, 0);
    }
    
    for (Character c: test.toCharArray()) {
        if (charMap.containsKey(c)) {
            charMap.put(c, charMap.get(c) + 1);
        }
    }
    

    Demo

    【讨论】:

      【解决方案3】:

      这里是英文字母计数应用程序不区分大小写的版本:

      public static void main(final String[] args) {
          System.out.println("Please enter a sentence to parse.");
          try (final Scanner input = new Scanner(System.in)) {
              final String userString = input.nextLine();
      
              final long[] symbols = new long[26];
              for (final char c : userString.toCharArray()) {
                  if ((c >= 'a') && (c <= 'z')) {
                      symbols[c - 'a']++;
                  } else if ((c >= 'A') && (c <= 'Z')) {
                      symbols[c - 'A']++;
                  }
              }
              for (int i = 0; i < 26; i++) {
                  System.out.println((char) ('a' + i) + ": " + symbols[i]);
              }
          }
      }
      

      “hello WORLD”的示例输出:

      a: 0
      b: 0
      c: 0
      d: 1
      e: 1
      f: 0
      g: 0
      h: 1
      i: 0
      j: 0
      k: 0
      l: 3
      m: 0
      n: 0
      o: 2
      p: 0
      q: 0
      r: 1
      s: 0
      t: 0
      u: 0
      v: 0
      w: 1
      x: 0
      y: 0
      z: 0
      

      【讨论】:

        【解决方案4】:
        public static void main(String args[]){
            //Convert below lower and upper arrays into one new upperlower map Map<Character, Integer>
            //char[] lower = new char[] {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
            //char[] upper = new char[] {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
            Map<Character, Integer> countMap = new TreeMap<>();
            Integer count;
            String inputStr = "Hello WORLD";
            char[] arr = inputStr.toCharArray();
        
            for(Character c : arr){
                count = 0;
                if(c == ' ')
                    continue;
                if(countMap.containsKey(c))
                    count = countMap.get(c);
                countMap.put(c, count+1);
            }
        
            Iterator<Entry<Character, Integer>> it = countMap.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<Character, Integer> pair = (Map.Entry<Character, Integer>)it.next();
                System.out.println(pair.getKey() + " = " + pair.getValue());
                it.remove(); // avoids a ConcurrentModificationException
        
                /*Check pair.getKey() contains on upperlower map if contains assign the new 
                  value into map */
        
            }
        
            //Finally loop the upperlower Map to display character occurence
        }
        

        认为这会对您有所帮助。

        【讨论】:

          【解决方案5】:

          使用 Google Guava 的 Multiset,您可以摆脱不必要的样板并在单行中计算区分大小写的直方图(使用 input.toLowerCase().toCharArray() 表示不区分大小写):

          String input = "hello WORLD";
          Multiset<Character> histogram = HashMultiset.create(
              Chars.asList(input.toCharArray()));
          

          直方图可以这样输出:

          public static final String ALPHABET = "abcdefghijklmnopqrstuvwxyz";
          //...
          final List<Character> caseSensitiveAlphabet 
              = Lists.newArrayList(Chars.asList(ALPHABET.toCharArray()));
          caseSensitiveAlphabet.addAll(
              Chars.asList(ALPHABET.toUpperCase().toCharArray()));
          
          for (char c : caseSensitiveAlphabet) {
              System.out.println(c + " : " + histogram.count(c));
          }
          

          【讨论】:

            【解决方案6】:

            在 Java 8 中,您可以这样解决问题:

                String input = "Hello WORLD";
            
                Map<Character, Integer> map = new TreeMap<>();
            
                "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
                        .chars()
                        .mapToObj(i -> (char) i)
                        .forEach(c -> map.put(c, 0));
            
                input.chars()
                        .mapToObj(i -> (char) i)
                        .forEach(c -> map.computeIfPresent(c, (k, v) -> v + 1));
            
                System.out.println(map);
            

            这将产生:

            {A=0, B=0, C=0, D=1, E=0, F=0, G=0, H=1, I=0, J=0, K=0, L= 1, M=0, N=0, O=1, P=0, Q=0, R=1, S=0, T=0, U=0, V=0, W=1, X=0, Y=0, Z=0, a=0, b=0, c=0, d=0, e=1, f=0, g=0, h=0, i=0, j=0, k= 0, l=2, m=0, n=0, o=1, p=0, q=0, r=0, s=0, t=0, u=0, v=0, w=0, x=0, y=0, z=0}

            【讨论】:

              【解决方案7】:

              这是不使用任何包的最简单的答案...

              这里我有一个字符串,首先我将此字符串转换为 chararray,然后我运行一个循环来计算此 chararray 中的字母数。

              由于每个字母至少出现一次,所以我将 1 分配给一个标志 c,它存储每个字母的出现次数。

              现在我运行嵌套循环来检查一个字母表是否出现了不止一次..如果确实出现了,我将标志 c 增加 1,然后我从 k=j 运行第三个嵌套循环以删除这个重复的字母表...

              这里 j 是重复字母表的索引,为了删除这个字母表,我将下一个 (j+1) 索引处的值分配给此 (j) 索引,并将索引 j+2 处的值分配给索引 j+1。 ...依此类推,直到我到达 n-1 索引,该索引现在被赋予第 n 个索引的值。

              删除这个重复的字母后,chararray 的大小减 1,因此我将 n 减 1。

                  public class AlphabetOccurance {
              public static void main(String[] args) {
                  String s;
                  s = "ASGFDTRRCJFYDCJHGJ";
                  char ch[] = s.toCharArray(); // converted string to chararray       
                   int i,j,k,c=1,n;
                   for (i=0; i<s.length();i++); // loop to find no. of alphabet in string
                   n=i;
                   System.out.println("number of charaters in string = " + n); 
                   for (i=0; i<n;i++)
                   {
                      for (j=i+1; j<n ;j++)
                      {
                          if (ch[j] == ch[i]) //if an alphabet if repeated...
                          {
                              c++; // if repeated alphabet found, increment count by 1
              
                              for (k=j; k<n-1;k++) //loop to delete repeated alphabet
                              {
                                  ch[k] = ch[k+1];//deleting repeated alphabet
                              }
                           n--; // after deleting repeated alphabet, n is decremented by 1
                          }
                       }
                     System.out.println("alphabet " + ch[i] + " occured " + c + " times");
              
                     c=1; // for counting of next alphabet, now initialized c back to 1
                   }  
              }}
              

              输出:

              字符串中的字符数 = 18

              字母 A 出现 1 次

              字母 S 出现 1 次

              字母 G 出现了 2 次​​p>

              字母 F 出现了 2 次​​p>

              字母 D 出现了 2 次​​p>

              字母 T 出现 1 次

              字母 R 出现 2 次​​p>

              字母 C 出现了 2 次​​p>

              字母 J 出现了 3 次

              字母 Y 出现了 1 次

              字母 H 出现 1 次

              【讨论】:

              • 拜托,下次尝试解释答案
              • 我已经编辑了我的答案,并尝试在 cmets 的帮助下尽可能简单地解释......希望现在更好。顺便说一句,谢谢你的建议。
              猜你喜欢
              • 1970-01-01
              • 2020-07-23
              • 1970-01-01
              • 2022-10-15
              • 1970-01-01
              • 2019-04-05
              • 2013-11-04
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多