洛谷P1012 拼数 C语言

这个题可以用字符串去做,接受字符来去计算大小,这里可以用到strcmp函数

str1 = "123"

str2 = "124"

strcmp(str1,str2)如果说str1比str2大就会返回大于0的数,一般是1;如果相等返回0,小于返回-1.

它是比较这两个字符串的ascll值来比较的,比方说3的ascll值就比4小,那么前面的都相同,那么就会返回-1。会一直比较到'\0'。这就出现一个问题,比方说23和231谁放在前面作为拼数的话比较大呢?肯定是23放在前面拼数的话比较大,但是23比231小一个字节,那么比较最后一个字符的时候,就会出现错误。所以这里就需要重新判断以下。(可能说的不是很清楚,看代码吧还是。)

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

int main()
{
    int n, i, j, k;
    int len_f;
    int len_l;
    int min;

    scanf("%d", &n);
    
    char input[n][10];
    char temp[10] = {0};

    memset(input, 0, sizeof input); // 初始化为0

    for (i = 0; i < n; i++){
        scanf("%s", &input[i]);
    }

    
    for (i = 0; i < n-1; i++){ // 这里就是冒泡排序,比较值的大小
        for (j = 0; j < n-1-i; j++){
            len_f = strlen(input[j]);
            len_l = strlen(input[j+1]);
            // 如果前面数值相等,但是某一个字符串长一点,那么判断就会有误(文章最后详解 1)
            if (input[j][0] == input[j+1][0] && len_f != len_l){
                if (len_f > len_l){
                    min = len_l;
                } else {
                    min = len_f;
                }
                for (k = 1; k < min; k++){
                    if (input[j][k] != input[j+1][k]){ //文章最后详解 2
                        break;
                    }
                }
                if (k == min){ // 前面的数都相等且长度短,那么就大,已经到某一个字符串的结尾了
                    // 如果时input[j] 135 input[j+1] 13 那么135 > 13
                    if (input[j][k] == '\0' && (input[j][0] > input[j+1][k])){ //详解3
                        continue;
                    }
                    if (input[j+1][k] == '\0' && (input[j+1][0] < input[j][k])){ // 详解4
                        continue; // 直接下次循环
                    }
                    else {
                        strcpy(temp, input[j]);
                        strcpy(input[j], input[j+1]);
                        strcpy(input[j+1], temp);
                        continue; // 直接下次循环
                    }
                    
                }
            } 
            if (strcmp(input[j], input[j+1]) >= 0){ // 判断j 是否大于j+1 
                continue;
            } else {
                // 如果j+1大于j,就交换位置
                strcpy(temp, input[j]);
                strcpy(input[j], input[j+1]);
                strcpy(input[j+1], temp);
            }
                
            
        }
    }
    
    for (i = 0; i < n; i++){
        printf("%s", input[i]);
    }
    printf("\n");

    return 0;
}

详解

首先来说我是用冒泡排序的方法来调整位置的,最大就在最前,最小就最后。(这里说的最大最小是做拼数的最大最小,不仅仅是数值上的大小。)

1、if (input[j][0] == input[j+1][0] && len_f != len_l) 这里是判断如果两个字符串的首字符相等,并且长度不等才执行if语句,因为如果长度相等那么strcmp就可以直接判断大小,就不需要进行额外的判断了。

2、第一点直接就判断的0的位置,那这里就直接从1开始判断,如果怕判断的过程当中,出现相同位置的字符不相等,那就直接退出,因为strcmp可以直接判断(不会判断到字符结尾,因为k<min)

3、进入到这里的if判断就证明两个字符串的数在结束之前都是相等的,比如13和135在13到结尾之前都相等,那么到这里if (input[j][k] == '\0' && (input[j][0] > input[j+1][k])),如果输入数据的时候13就在135前面并且13的1大于135的5时就直接跳过本次循环,什么意思?也就是说如果输入的是13 135那么拼数的时候13513肯定比13135要大啊,那么这里就要判断先结束的那个字符串它的首个数字是否比另一个字符串的k位置的数大,如果大于就不用换位,如果小就要换位。可以理解以下135 13和635 63.

4、这里如果你理解了3那么理解这里也就很简单了if (input[j+1][k] == '\0' && (input[j+1][0] < input[j][k])),这里是如果输入的是135 13此时13在后面了,那么就是后面这个字符串先结束,那么如果第一个字符串的k位置的数值比后面这个字符串的首字符大,是不是就不用换位了?所以这里就最直接continue了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GospeLLLLLL

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值