简体   繁体   English

字符串中的字符计数-C程序

[英]Character Counting in a String - C program

I have written a C program. 我写了一个C程序。 It's a character counting program. 这是一个字符计数程序。 I will give input as below 我将输入如下

Input: ABCAPPPRC 输入: ABCAPPPRC
And need as output: A2B1C2P3R1 . 并需要作为输出: A2B1C2P3R1

But it gives output as A2B1C2A1P3P2P1R1C1 . 但是它给出的输出为A2B1C2A1P3P2P1R1C1 It basically doing as per the logic I have written in program. 它基本上按照我在程序中编写的逻辑进行操作。 But I don't want to count the characters of string which have already been counted. 但是我不想计算已经计算的字符串字符。 Can you suggest what logic I should implement for this? 您能建议我为此实现什么逻辑吗?

#include <stdio.h>

int main()
{
        char str[30]= "ABCAPPPRC";
        char strOutPut[60]="";
        char *ptr= &str, *ptr2=&str;
        char ch='A';
        int count=0;
        puts(str);

        while (*ptr !=NULL)
        {
                count =0;
                ch = *ptr;
                while (*ptr2!= NULL)
                {
                        if (*ptr2 == ch) count++;
                        ptr2++;
                }
                printf("%c%d",*ptr, count);
                ptr++;
                ptr2 = ptr;
        }
}

You need to separate the counting from the printing. 您需要将计数与打印分开。

  1. The first loop goes through the input and counts the number of occurrences of each character, storing the counts in an array indexed by the character code. 第一个循环遍历输入,并计算每个字符的出现次数,并将计数存储在由字符代码索引的数组中。
  2. The second loop goes through the array of counts and prints the character corresponding to a non-zero count followed by that count. 第二个循环遍历计数数组,并打印与非零计数相对应的字符,然后打印该计数。

For example: 例如:

#include <stdio.h>

int main(void)
{
    char str[] = "ABCAPPPRC";
    int counts[256] = { 0 };

    puts(str);

    for (char *ptr = str; *ptr != '\0'; ptr++)
        counts[(unsigned char)*ptr]++;
    for (int i = 0; i < 256; i++)
    {
        if (counts[i] != 0)
            printf("%c%d", i, counts[i]);
    }
    putchar('\n');
    return(0);
}

Sample output: 样本输出:

ABCAPPPRC
A2B1C2P3R1

I could not understand the first for loop. 我不明白第一个for循环。 Could you please explain it? 你能解释一下吗?

The for control line steps through the string str one character at a time. for控制行一次穿过字符串str一个字符。 It is the for loop equivalent of the outer while loop in your original code. 它与原始代码中的外部while循环的for循环等效。

char *ptr = str;
...
while (*ptr != '\0')
{
    ...
    ptr++;
}

The body of the loop converts *ptr (a plain char ) into an unsigned char (so that it is guaranteed to be positive), and then uses that value as an index into the array counts . 循环的主体将*ptr (纯char )转换为unsigned char (以确保为正数),然后将该值用作数组counts的索引。 Thus, for example, on the first iteration, A is mapped to 65, and counts[65] is incremented. 因此,例如,在第一次迭代中, A映射到65,并且counts[65]增加。 Thus, for each character code, the loop increments the count corresponding to that character code each time the character is encountered in the string. 因此,对于每个字符代码,每次在字符串中遇到字符时,循环都会增加与该字符代码相对应的计数。

The second loop then picks out the non-zero counts, printing the character code as a character followed by its count. 然后,第二个循环选择非零计数,将字符代码打印为字符,然后打印其计数。

(Incidentally, you should have been getting a compilation warning from the original char *ptr = &str about a type mismatch between char * and char (*)[30] . Learn when to put ampersands in front of array names — you seldom do it unless there is also a subscript after the array name. Thus, &array is usually — but not always — wrong; by contrast, &array[0] is very often valid. Also note that on some machines, NULL is defined as ((void *)0) and this elicits a warning when you compare it to a plain char , as you did with while (*ptr != NULL) . You should compare characters to '\\0' as in my rewrite; you should reserve NULL for use with pointers.) (顺便说一句,您本来应该从原始char *ptr = &str收到关于char *char (*)[30]之间的类型不匹配的编译警告。了解何时将“&”号放在数组名称的前面–很少这样做)除非在数组名后还有下标。因此, &array通常-但并非总是-错误;相反, &array[0]通常是有效的。另外请注意,在某些计算机上, NULL定义为((void *)0) ,这会在您将其与纯char进行比较时引发警告,就像while (*ptr != NULL) ,您应该像在重写中那样将字符与'\\0'进行比较;应保留NULL以供使用带有指针。)

str is alerady a character pointer, so when you do this: char *ptr= &str you convert a pointer to pointer to character to a char* . str通常是一个字符指针,因此,当您执行以下操作时: char *ptr= &str会将字符指针转换为char* Loose the ampersand( & ). 松开“& &

Also in the inner cycle you should check if the given value of ch has already been processed. 同样在内部循环中,您应该检查ch的给定值是否已被处理。 In the case you use when ptr is pointing to the second A you should just continue, because you have already added the number of A -s in the answer. 如果您使用ptr指向第二个A ,则应该继续,因为您已经在答案中添加了A -s的数量。

Your solution is far from optimal. 您的解决方案远非最佳。 I strongly suggest you lookup counting sort . 我强烈建议您查询计数排序 It will make your solution faster but also will make it simpler. 这将使您的解决方案更快,但也会使其更简单。

@ Jonathan your solution is correct only when string characters are given in ascending order like ABCDEF, but it gives problem when character order is changed. @ Jonathan仅当以ABCDEF之类的升序给出字符串字符时,您的解决方案才是正确的,但是当改变字符顺序时,它会带来问题。 Input string is "ABAPPPRCC" and required output is A2B1P3R1C2. 输入字符串为“ ABAPPPRCC”,所需的输出为A2B1P3R1C2。 Here in this case your solution will change out put to A2B1C2P3R1. 在这种情况下,您的解决方案将更改为A2B1C2P3R1。

Below program gives character count without changing string formation. 下面的程序在不更改字符串格式的情况下给出了字符计数。

char *str= "ABAPPPRCC";
    char strOutPut[30]="";
    char *ptr = str, *ptr2 = str;  
    char ch='A';
    int count=0, i = 0 , total_print = 0;
    puts(str);

    while (*ptr != '\0')
    {
            count =0;
            ch = *ptr;
            while (*ptr2!= '\0')
            {
                    if (*ptr2 == ch) count++;
                    ptr2++;
            }
            for( i = 0; i < total_print ; i++ )
            {
                if ( ch == strOutPut[i] )
                {
                     i =  total_print + 1;
                       break;
                }
            }  

            if( i <= total_print )
            {
                    printf("%c%d",*ptr, count);
                    strOutPut[total_print++] = ch;
            }
            ptr++;
            ptr2 = ptr;
    }
#include <stdio.h>

int main(void){
    const char noncountchar = '\x11';
    char str[30]= "ABCAPPPRC";
    char strOutPut[60]="";
    char *ptr, *ptr2;
    char ch;
    int count=0, len=0;
    puts(str);

    for(ptr=str;ch=*ptr;++ptr){
        if(ch == noncountchar) continue;
        count =1;
        for(ptr2=ptr+1;*ptr2;++ptr2){
            if (*ptr2 == ch){
                *ptr2 = noncountchar;
                ++count;
            }
        }
        len += sprintf(strOutPut+len, "%c%d", *ptr, count);
    }
    printf("%s", strOutPut);
    return 0;
}

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

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