数串

来源:互联网 发布:手机lol视频软件 编辑:程序博客网 时间:2024/06/07 10:54

题目描述
设有n个正整数,将他们连接成一排,组成一个最大的多位整数。
如:n=3时,3个整数13,312,343,连成的最大整数为34331213。
如:n=4时,4个整数7,13,4,246连接成的最大整数为7424613。
输入描述:
有多组测试样例,每组测试样例包含两行,第一行为一个整数N(N<=100),第二行包含N个数(每个数不超过1000,空格分开)。
输出描述:
每组数据输出一个表示最大的整数。

示例1
输入
2
12 123
4
7 13 4 246

输出
12312
7424613

初步解题思路:
1.第一遍看到题目 —> 很简单的字符串比较题。
2.主要要用到的函数就是 algorithm 里面的 sort 函数,用来对字符串排序,最后的输出结果也就是排完序后顺序输出的结果
3.在使用 sort 函数的时候,因为本题是对 字符串 进行排序 , 所以要首先实现method 即 字符串如何比较大小的函数。
sort() 函数讲解: sort(object1 , object2, method)函数中一共有三个参数,其中前两个就是进行比较的两个对象,这两个对象可以是任意适当类型,只要实现比较方法(method)即可。method 是 一个返回值为 bool 类型的函数,可以决定sort的排序方法 ,其中主要包括:1.以什么为标准排序 2.是从大到小排还是从小到大排。(具体的使用实例见本题代码)

代码调试过程:
1.有了初步的解题思路之后,开始上手写代码。

//第一次运行的代码#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;bool method(char *num1 , char *num2){    int t;    t = strcmp(num1,num2);    if(t >= 0)        return true;    else        return false;}void ADD(char **num,int n){    int i;    char *temp;    temp = new char[4];    sort(num,num+n,method);    for(i = 0 ; i < n ; i++)        printf("%s",num[i]);}int main(){    int N,i;    char **num;    scanf("%d",&N);    num = new char*[N];    for(i = 0 ; i < N ; i ++)        num[i] = new char[4];    for(i = 0 ; i < N ; i ++)        scanf("%s",num[i]);    ADD(num , N);}/*第一次代码运行很顺利,测试用例也都通过,放到评测系统里面跑了一下,case通过率只有40%*//*评测系统可谓是很良心了,给了一组测试数据的正确答案,以及提交的代码跑出答案,用赤裸裸的事实告诉我 ---> 你的代码不通过*/

评测系统给出的实例:
这里写图片描述

代码错误分析:
1.比较之后发现问题出在了 821 和 82 上面,按照初步解题思路,821 确实大于 82 ,但是进一步分析 可得 : 821-82 确实要比 82-821 要小,原因就在于 82 和 821 的前一部分完全匹配,而821放在前面是 第三个数使其本身的 1 ,而当 82 放在前面是 第三个数是 下一个数 821 的第一个数 8 , 所以第二种排列方法所得结果要大于第一个方法。
2.进一步分析发现,这种情况只会出现在 前一个数 与 后一个数 的位数不相等,且后一个数是前一个数的前缀的情况下。
3.找到了 导致代码错误的原因,以及代码出错的位置,下一步就是修改调试代码。

代码修改思路
1.当出现 代码错误分析 中情况时,假设两个数 abcdef 与 abc ,基于一开始的代码的运行结果应该是 abcdef-abc , 但是正确情况下,应该有两种排列可能:
abcdef-abc 以及 abc-abcdef ,而决定这两种排列那个正确的主要就在于 a 和 d 的大小(即这两种情况第一次出现不一样的数据的地方)。
2.所以在出现这种状况是就要进一步比较 a 和 d 的大小。
3.a>d 时abc-abcde,此时在sort 后结果里需要将 abc 与 abcdef 进行交换;
a< d时结果是 abcdef-abc ,此时不需要做出改变;那么 a = d 时的结果呢?
4.当 a = d 时,abcdef 既可以写成 abcaef ,那么排列的两种情况就变成
abcaef-abc 以及 abc-abcaef , 此时就变成比较 e 和 b 的大小。
5.基于 第3点 和 第4点,可以总结成 比较 两种排列的结果。
6.还有一个需要考虑的问题,当需要对sort 后的数组做出改变时,要进一步比较的指标往前推一位,例如当前比较的是 第 i 个 数 和 第 i+1 个数 ,如果此时他们需要换位置,那么换位之后,需要向前比较以为,即比较此时的第 i-1 个数 和 第 i 个数。

最终正确代码:

#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;bool method(char *num1 , char *num2){    int t;    t = strcmp(num1,num2);    if(t >= 0)        return true;    else        return false;}void ADD(char **num,int n){    int i,flag;    char temp1[8],temp2[8] ;//用来存放 2 中可能的排列结果    char *temp;  //用来实现字符串的交换    temp = new char[4];    sort(num,num+n,method);    for(i = 0 ; i < n-1 ; i ++){        if(strlen(num[i]) > strlen(num[i+1])){            strcpy(temp1 , num[i]);            strcpy(temp2 , num[i+1]);            strcat(temp1,num[i+1]);  //第一种排列结果            strcat(temp2,num[i]);  //第二种排列结果            flag = strcmp(temp1 , temp2);            if(flag < 0){   //第2中排列比较大                temp = num[i];                num[i] = num[i+1];                num[i+1] = temp;                if(i-2 >= -1)                    i = i - 2;    //向前比较一个            }        }    }    for(i = 0 ; i < n ; i++)        printf("%s",num[i]);}int main(){    int N,i;    char **num;    scanf("%d",&N);    num = new char*[N];    for(i = 0 ; i < N ; i ++)        num[i] = new char[4];    for(i = 0 ; i < N ; i ++)        scanf("%s",num[i]);    ADD(num , N);}
原创粉丝点击