繁体   English   中英

计算字符串中的字符频率(Java)

[英]Counting Character Frequency in String(Java)

因此,由于我被分配了一个问题,即查找字符串中字符的频率以下是来自 geeksforgeeks 的示例,但我不明白它在做什么? 所以我需要帮助某人向我解释它。

Input : geeksforgeeks
Output :
Number of Occurrence of g is:2
Number of Occurrence of e is:4
Number of Occurrence of k is:2
Number of Occurrence of s is:2
Number of Occurrence of f is:1
Number of Occurrence of o is:1
Number of Occurrence of r is:1

这是代码


class NoOfOccurenceOfCharacters { 
    static final int MAX_CHAR = 256; 
  
    static void getOccuringChar(String str) 
    { 
        // Create an array of size 256 i.e. ASCII_SIZE 
        int count[] = new int[MAX_CHAR]; 
  
        int len = str.length(); 
  
        // Initialize count array index 
        for (int i = 0; i < len; i++) 
            count[str.charAt(i)]++; 
  
        // Create an array of given String size 
        char ch[] = new char[str.length()]; 
        for (int i = 0; i < len; i++) { 
            ch[i] = str.charAt(i); 
            int find = 0; 
            for (int j = 0; j <= i; j++) { 
  
                // If any matches found 
                if (str.charAt(i) == ch[j])  
                    find++;                 
            } 
  
            if (find == 1)  
                System.out.println("Number of Occurrence of " + 
                 str.charAt(i) + " is:" + count[str.charAt(i)]);             
        } 
    } 
    public static void main(String[] args) 
    { 
        Scanner sc = new Scanner(System.in); 
        String str = "geeksforgeeks"; 
        getOccuringChar(str); 
    } 
} 

输出

Number of Occurrence of g is:2
Number of Occurrence of e is:4
Number of Occurrence of k is:2
Number of Occurrence of s is:2
Number of Occurrence of f is:1
Number of Occurrence of o is:1
Number of Occurrence of r is:1

count[str.charAt(i)]++实际上是做什么的? 我对这部分感到困惑,请有人向我解释一下吗?

为什么有find = 0

好吧, count是一个有 256 个插槽的int[]

int count[] = new int[MAX_CHAR]; // MAX_CHAR is 256

您的算法定义MAX_CHAR = 256 ,因为它假定字符串仅包含 8 位 ASCII 字符。

[0, 0, ..., 0, 0] // 256 slots

现在您正在迭代字符串str每个字符并将其强制转换为整数(请参阅Java 中基元的类型转换)。 A将被转换为 65( ASCII 表), B将被转换为 66,依此类推。 强制转换的int是要递增的插槽。 所以字符串A会导致索引 65 处的整数增加。 你的问题主要是关于

count[str.charAt(i)]++

这转化为:

char c = str.charAt(i);    // c = A
int index = c;             // c = A, casted to an int = 65
count[index]++             // increments the int at position 65

结果:

[0, 0, ..., 1, ..., 0, 0]
            ^ index 65

下一个A将再次在索引 65 处增加 int:

[0, 0, ..., 2, ..., 0, 0]
            ^ index 65

使用HashMapString存储字符和频率循环遍历String每个字符

例如:

(charCount.containsKey(arr1[i])) {
            charCount.put(arr1[i], charCount.get(arr1[i]) + 1);
       
        

因此, count[str.charAt(i)]++包括许多不同的阶段,可以简化如下以便更好地理解:

char currentChar = str.charAt(i); // getting the current char to in the string
int value = count[currentChar]; // Get the current counter value
value = value + 1; // Increasing the current appearnce of this character by one
count[currentChar] = value; // Update the counter value

基本上,您的代码假定您使用的是 ASCII 字符串(可能有 255 个不同的字符)并计算每个字符。

看起来好像预期目标是按照给定字符串中首次出现的顺序打印出重复的字符。 为了做到这一点,我们从左到右逐步遍历str

for (int i=0; i < len; ++i) {

数组chstr长度相同,用于跟踪我们迄今为止检查过的str字符:

    ch[i] = str.charAt(i);

接下来,我们计算字符str.charAt(i)ch[0] .. ch[i]的次数,在find累加计数:

   int find = 0;
     //...
   for (int j = 0; j <= i; j++) { 
        if (str.charAt(i) == ch[j])  
            find++;                 
   } 

如果find == 1 ,这意味着我们第一次遇到字符str.charAt(i) ,我们应该打印出它的频率:

    if (find == 1)
        System.out.println("Number of Occurrence of " + 
            str.charAt(i) + " is:" + count[str.charAt(i)]);  
}           

请注意,在任何给定时刻, ch[0] .. ch[i]中的字符与字符str.charAt(0) .. str.charAt(i) ,因此额外的ch数组并不是真的必要的。 我们可以直接在str的前i字符中计算str.charAt(i)的出现次数,如下所示:

for (int i = 0; i < str.length(); ++i){
    int find = 0;
    for (int j = 0; j <= i; ++j) {
        if (str.charAt(j) == str.charAt(i))
            ++find;
    }
    if (find == 1)
        System.out.println("Number of Occurrence of " + 
             str.charAt(i) + " is:" + count[str.charAt(i)]);             
}

另一种方法是不需要重新计算字符的方法,前提是它们显示后不再需要频率计数。 您可以使用频率计数来跟踪哪些字符的频率已打印和未打印,方法是 1) 在打印出来后将频率计数清零 2) 仅打印频率非零的字符:

for (int i = 0; i < str.length(); ++i) {
    if (count[str.charAt(i) > 0) {
        System.out.println("Number of Occurrence of " + 
             str.charAt(i) + " is:" + count[str.charAt(i)]);
        count[str.charAt(i)] = 0;
    }
}

优化方式

import java.util.ArrayList;
import java.util.List;
public class HelloWorld{
        
    static final int MAX_CHAR = 256;
    static List<Character> sequence = new ArrayList<>();
    static void getOccuringChar(String s){
        int count[] = new int[MAX_CHAR];
        for(int i=0;i<s.length();i++){
            count[s.charAt(i)]++;
            if(!sequence.contains(s.charAt(i)))
                sequence.add(s.charAt(i));
                
        }
        
        for(int i=0;i<sequence.size();i++)
                System.out.println("Number of Occurrence of "+sequence.get(i)+" is:"+count[sequence.get(i)]);
    }
    
    public static void main(String arg[]){
        getOccuringChar("geeksforgeeks");
    }
}

输出是

Number of Occurrence of g is:2
Number of Occurrence of e is:4
Number of Occurrence of k is:2
Number of Occurrence of s is:2
Number of Occurrence of f is:1
Number of Occurrence of o is:1
Number of Occurrence of r is:1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM