记录0~9各数字出现的次数

探讨C语言中使用pow函数进行数字位数统计及位操作的常见问题,包括类型转换错误与精度问题,分享解决方案。

问题:编写一个程序,输入一个整数,输出0~9各个数字在该整数中出现的次数。(《C语言程序设计》夏宽理u3t1)
我一开始写的代码:

#include <stdio.h>
#include<math.h>

int main()
{   int x,index;
    int a=0,b=0,c=0,d=0,e=0,f=0,g=0,h=0,i=0,j=0,n=1;
    printf("请输入一个整数:\n");
    scanf("%d",&x);
    while(pow(10,n)<x) n++;  //x是n位数
    for(index=1;index<=n;index++)
    **switch(x%(pow(10,index))/(pow(10,index-1)))**//报错!
    {
        case 0:a++;break;
        case 1:b++;break;
        case 2:c++;break;
        case 3:d++;break;
        case 4:e++;break;
        case 5:f++;break;
        case 6:g++;break;
        case 7:h++;break;
        case 8:i++;break;
        case 9:j++;break;
    }
    printf("0:%d  1:%d  2:%d  3:%d  4:%d  5:%d  6:%d  7:%d  8:%d  9:%d",a,b,c,d,e,f,g,h,i,j);
    return 0;
}

加粗的这行有报错,它是这样说的:大意:
“%”的操作数出现了问题。难道是pow(10,index)不是整型吗?
于是我做了如下改变:
原来:switch(x%(pow(10,index))/(pow(10,index-1)))
后来:switch(x%(int)(pow(10,index))/(int)(pow(10,index-1)))
果然就没有报错了!百度了一下,发现pow函数的两个参数和函数值都是double型!

但是测验了一下,发现比较小的数字都能得到正确结果
在这里插入图片描述
在这里插入图片描述
但是如果数字比较长,就会出错
在这里插入图片描述
在这里插入图片描述
或许是int对数字大小的要求导致不能正确算出比较大的数吧?但是奇怪的是12345在int的取值范围内,为什么也会出错呢?

后来我修改了一下,因为不知道具体是哪里超了范围(假如出错的原因是超范围的话),就改动了很多地方,如下图所示。把三处int改成了long,把一个%d改成了%ld。但是这样改动后得到的结果没有任何变化。
int→long
----------------------------------------分界线------------------------------------------------------

*后来我又遇到了一个类似的问题,不知道与之前这个问题是否同理。问题源自u3t6。
以下这个代码试图提取整数x的倒数第i位。当我取x为2345,i为2时结果为6:

#include <stdio.h>
#include<math.h>

int main()
{   int x=2345;int i=2;
    printf("%d",(x%(int)pow(10,i))/(int)pow(10,i-1));
    return 0;
}

在这里插入图片描述
当我不采用x这个变量,并且把2345直接代到算式中时,答案仍为6

#include <stdio.h>
#include<math.h>

int main()
{   int i=2;
    printf("%d",(2345%(int)pow(10,i))/(int)pow(10,i-1));
    return 0;
}

在这里插入图片描述
现在复原x,而不采用i这个变量,把2直接代入式子,答案就变成了正确答案4!

#include <stdio.h>
#include<math.h>

int main()
{   int x=2345;
    printf("%d",(x%(int)pow(10,2))/(int)pow(10,1));
    return 0;
}

在这里插入图片描述
如果我两个都不采用,像下面这样,答案也是正确的。

#include <stdio.h>
#include<math.h>

int main()
{
    printf("%d",(2345%(int)pow(10,2))/(int)pow(10,1));
    return 0;
}

这说明发生问题的原因在与pow后面的第二个参数。前面说pow函数的参数必须是double类型,因此把int放在这里确实不妥。可是当我把i定义为一个double类型的数时,结果仍然是6。

#include <stdio.h>
#include<math.h>

int main()
{
    double i=2;
    printf("%d",(2345%(int)pow(10,i))/(int)pow(10,i-1));
    return 0;
}

这是为什么呢?


已解决:这是因为<math.h>里的pow函数结果值有时会不太精确,可能会用近似的值表示,如100表示成99.99999等。再强行取整的话,就变成了99!

<think>好的,我需要帮助用户解决如何用C语言统计字符串中09数字出现的次数。用户已经提供了一些参考资料,我得仔细看看这些引用中的代码示例,然后综合出一个合适的解决方案。首先,用户的问题很明确:统计字符串中每个数字0-9)的出现次数。我需要确保代码能够正确遍历字符串,识别每个字符是否为数字,并更新对应的计数器。看引用[3]和引用[4]中的例子,他们使用数组来记录每个数字的出现次数。例如,引用[3]中的代码使用a[10]数组,初始化所有元素为0,然后遍历输入的字符,当字符是数字时,通过c-&#39;0&#39;得到对应的索引,然后增加该位置的计数值。这种方法比较高效,因为直接利用字符的ASCII值转换,不需要复杂的判断。 引用[4]则是用switch-case来处理每个字符,这种方法虽然可行,但代码量较大,不如数组索引直接。所以我觉得采用引用[3]的方法更简洁。另外,需要注意字符串输入的方式。引用[1]和[3]使用gets或者getchar,而引用[4]提到gets可以接收带空格的字符串,而scanf可能不行。所以用户输入可能需要处理包含空格的情况,这时候gets更合适,但需要注意gets的安全性问题,不过在这题中可能不是重点。接下来,我需要确保代码结构正确。主函数中应该定义一个大小为10的整型数组来存储每个数字的出现次数,初始化为0。然后读取输入字符串,遍历每个字符,如果是数字字符,就将对应的数组元素加1。最后循环输出每个数字及其出现次数。 可能需要注意的边界情况包括:字符串中没有数字,或者输入中有大写字母或其他字符,但题目只关心0-9数字,所以其他字符可以忽略。另外,用户提供的引用[5]中的代码比较复杂,处理了字母和其他字符,但用户的需只需要数字部分,所以可以简化处理,不需要考虑字母的情况。综合这些信息,我应该编写一个使用数组,通过字符转换索引的方法,简洁高效地统计0-9出现次数的程序。同时,代码需要包含必要的输入输出,并处理可能的输入方式,比如使用gets或fgets来读取带空格的字符串。最后,测试一下代码,比如输入一个包含多个数字的字符串,检查输出是否正确统计每个数字次数。例如,输入"a1b23c456",应该输出1出现1次,2出现1次,3出现1次,4出现1次,5出现1次,6出现1次,其他数字出现0次。</think>在C语言中统计字符串中0-9数字字符的出现次数,可以通过数组索引直接映射字符实现。以下是分步解决方案: ### 方法实现 1. **定义计数器数组** ```c int counts[10] = {0}; // 初始化所有数字计数器为0 ``` 2. **字符串输入与遍历** ```c char str[200]; gets(str); // 输入字符串(含空格) for(int i=0; str[i]!=&#39;\0&#39;; i++) { if(str[i] >= &#39;0&#39; && str[i] <= &#39;9&#39;) { counts[str[i]-&#39;0&#39;]++; // 字符转数字索引 } } ``` 3. **结果输出** ```c for(int i=0; i<10; i++) { printf("%d出现次数:%d\n", i, counts[i]); } ``` ### 完整代码示例 ```c #include <stdio.h> int main() { int counts[10] = {0}; // 初始化计数器数组[^3] char str[200]; printf("输入字符串:"); gets(str); // 读取含空格的字符串[^4] for(int i=0; str[i]!=&#39;\0&#39;; i++) { if(str[i] >= &#39;0&#39; && str[i] <= &#39;9&#39;) { counts[str[i]-&#39;0&#39;]++; // 字符转数组索引[^3] } } for(int i=0; i<10; i++) { printf("%d出现次数:%d\n", i, counts[i]); } return 0; } ``` ### 关键点解析 1. **ASCII映射**:通过`str[i]-&#39;0&#39;`将字符&#39;0&#39;-&#39;9&#39;转换为整型0-9,直接作为数组索引 2. **时间复杂度**:$O(n)$线性复杂度,n为字符串长度 3. **空间复杂度**:$O(1)$固定使用10个整型空间[^3]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值