C语言,50求助

P1307 [NOIP2011 普及组] 数字反转

P_udding @ 2024-02-26 22:18:18

这个代码不知道问题在哪里,五位及以上的不会0开头,但是五位以下就好像识别不了0,是为什么? 比如输入120,会输出021,但是如果我直接在代码里赋值120就没有这个情况,五位及以上70000也能正确输出7,-3000输出-3


#include <stdio.h>
int main()
{
    char a[11];
    scanf("%s",&a);
    int i=0;
    if(a[0]=='-'){
        i++;
        printf("-");
    }
    int j=10;
    for(;j>=0;j--){
        if(a[j]!='\0'&&a[j]!='0'){
            break;
        }
    }
    for(;j>=i;j--){
        printf("%c",a[j]);
    }
    return 0;
}

by 杜都督 @ 2024-02-27 02:11:45

一种可行修改

#include <stdio.h>
int main()
{
    char a[12];
    scanf("%s",&a);
    int i=0;
    if(a[0]=='-'){
        i++;
        printf("-");
    }
    int j=0;
    while(a[j+1]!='\0'){
        j++;
    }
    for(;j>0;j--){
        if(a[j]!='0'){
            break;
        }
    }
    for(;j>=i;j--){
        printf("%c",a[j]);
    }
    return 0;
}

by P_udding @ 2024-03-06 17:58:47

@杜都督 可以了!!谢谢!不过为什么要先遍历出\0再遍历非0,不理解为什么一起遍历就会出问题(还只有部分有问题),这个应该去学什么内容?


by 杜都督 @ 2024-03-06 18:25:08

@P_udding 你说的这种方法其实也是可以的,这是另一种可行修改:

#include <stdio.h>
int main()
{
    char a[12]={0};
    scanf("%s",&a);
    if(a[0]=='0'){
        printf("0");
        return 0;
    }
    int i=0;
    if(a[0]=='-'){
        i++;
        printf("-");
    }
    int j=10;
    for(;j>=0;j--){
        if(a[j]!='\0'&&a[j]!='0'){
            break;
        }
    }
    for(;j>=i;j--){
        printf("%c",a[j]);
    }
    return 0;
}

by 杜都督 @ 2024-03-06 18:31:12

@P_udding 但是这种情况下需要将 a[] 初始化为全 0(注意不是字符是数字),否则由于 a[] 是局部变量,未初始化的情况下数组内的所有值就是随机的

经过 scanf() 后,a[] 中的部分值会被输入数据的值覆盖,但并不是所有输入数据都能完整地覆盖所有 a[] 中的值,那么 a[] 末尾那些由于输入数据长度不足而导致没有被覆盖的地方就仍然是随机值,那么此时如果使用你的方法去反向遍历,很有可能会在随机值的部分就 break,而此时循环还没有遍历到真正的数据本体,所以会导致出错


by 杜都督 @ 2024-03-06 18:41:00

@P_udding 解决的方法也很简单,就像之前所说的,使用 char a[12]={0}; 将数组的值全部初始化为 0(其实就是 '\0',它的十进制值就是 0),这样就不在存在随机值,a[] 的末尾在输入后将会是一堆 '\0'

但这样还是不能全A,因为无法处理仅输入一个 0 的情况,这个问题的解决方法也很简单,可以像我上面的代码那样对 0 做特判:

if(a[0]=='0'){
    printf("0");
    return 0;
}

当然也可以选择删掉这个特判,把第一个 for 改成:

for(;j>0;j--){

by 杜都督 @ 2024-03-06 18:43:26

@P_udding 顺便一提,根据题意,字符数组的大小应该设为 12 会更合适一些,因为字符串结尾的 '\0' 也会占用1个单位的空间


by 杜都督 @ 2024-03-06 18:49:57

@P_udding 当然,另一个可行的方案是让 j\text{字符串长度 }-1 作为起点,这样判断的条件就不需要加 '\0' 那部分了,这种情况下同样需要更改第一个 for 或做特判


by 杜都督 @ 2024-03-06 19:46:13

@P_udding 之前的代码都是基于你的思路来的,我写了一个更简洁的版本,你也可以参考一下:

#include <stdio.h>
#include <string.h>

const int MAX_LEN = 11 + 10; 

int main() {
    char num[MAX_LEN];
    scanf("%s", num);

    if (num[0] == '-') {
        printf("-");
    }
    int flag = 0;
    for (int i = strlen(num) - 1; i > 0; --i) {
        if (num[i] != '0') {
            flag = 1;
        }
        if (flag) {
            printf("%c", num[i]); 
        }
    }
    if (num[0] != '-') {
        printf("%c\n", num[0]);
    }

    return 0;
}

by P_udding @ 2024-03-06 21:47:20

@杜都督 非常谢谢!!解释的很清楚!不过我还是有点点问题想问一下,为什么你的那个代码数组是定义在函数体内的但是却好像没有随机?可以用“0”遍历 @杜都督


by 杜都督 @ 2024-03-06 23:02:37

@P_udding 我这个也是有随机的,但是我是从 \text{字符串长度 }−1 下标处开始遍历的,直接跳过了数组末尾没有被赋值的部分,所以每一个遍历到的元素都是字符串中的有效字符


| 下一页