0

我写了一个C程序。这是一个字符计数程序。我将提供如下输入

输入: ABCAPPPRC
并需要作为输出: A2B1C2P3R1

但它给出的输出为A2B1C2A1P3P2P1R1C1. 它基本上按照我在程序中编写的逻辑进行。但我不想计算已经计算过的字符串的字符。你能建议我应该为此实施什么逻辑吗?

#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;
        }
}
4

4 回答 4

4

您需要将计数与打印分开。

  1. 第一个循环遍历输入并计算每个字符的出现次数,将计数存储在由字符代码索引的数组中。
  2. 第二个循环遍历计数数组并打印对应于非零计数的字符,然后是该计数。

例如:

#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);
}

样本输出:

ABCAPPPRC
A2B1C2P3R1

我无法理解第一个for循环。你能解释一下吗?

for控制线str一次一个字符地遍历字符串。它是原始代码for中外部循环的循环等效项。while

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

循环体将*ptr(a plain char) 转换为 an unsigned char(以保证它是正数),然后将该值用作数组的索引counts。因此,例如,在第一次迭代时,A映射到 65,并counts[65]递增。因此,对于每个字符代码,每次在字符串中遇到该字符时,循环都会增加与该字符代码对应的计数。

然后第二个循环挑选出非零计数,将字符代码打印为一个字符,然后是它的计数。

(顺便说一句,您应该从原始版本中收到关于和char *ptr = &str之间类型不匹配的编译警告。了解何时在数组名称前面放置 & 符号 - 除非数组名称后面还有一个下标,否则您很少这样做。因此,是通常 - 但并非总是 - 错误;相比之下,通常是有效的。另请注意,在某些机器上,被定义为,当您将其与普通 进行比较时,这会引发警告,就像您对 . 所做的那样。您应该将字符与as进行比较在我的重写中;您应该保留与指针一起使用。)char *char (*)[30]&array&array[0]NULL((void *)0)charwhile (*ptr != NULL)'\0'NULL

于 2013-05-06T06:15:45.403 回答
1

str已经是一个字符指针,所以当你这样做时:char *ptr= &str你将一个指向字符的指针转换为一个char*. 松开与号 ( &)。

同样在内部循环中,您应该检查给定的值ch是否已经被处理。如果您在 ptr 指向第二个时使用,A您应该继续,因为您已经A在答案中添加了 -s 的数量。

您的解决方案远非最佳。我强烈建议您查找计数排序。它将使您的解决方案更快,但也会使其更简单。

于 2013-05-06T06:17:18.440 回答
1

@乔纳森您的解决方案仅在字符串字符以ABCDEF之类的升序给出时才是正确的,但是在更改字符顺序时会出现问题。输入字符串为“ABAPPPRCC”,所需输出为 A2B1P3R1C2。在这种情况下,您的解决方案将变为 A2B1C2P3R1。

下面的程序在不改变字符串格式的情况下给出字符数。

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;
    }
于 2013-05-06T08:04:23.540 回答
0
#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;
}
于 2013-05-06T07:55:23.787 回答