题目
拼数
自定义字符串排序
思路
经过观察可以知道:越高位的数越大,这个数就应该排在越前面的位置,比如 4321 4321 4321 和 4331 4331 4331,则 4331 4331 4331 应该排在前面。
所以将给出的整数转为字符串更容易操作。
将数转为字符串之后,可以对这个字符串数组进行排序,排序规则如下:
对两个字符串从左往右遍历:
- 如果对应位置的字符相同则相同,否则直到对应位置的字符不相同,字符串大小由第一个不相同的字符大小决定;
- 如果其中某个字符串的长度小于另一个,也就是说字符串 a a a 是字符串 b b b 的前缀,则判断字符串 b b b 的首尾字符大小:
2.1 如果字符串 b b b 的首字符大于字符串 b b b 的尾字符,则规定字符串 b b b 小于字符串 a a a
2.2 如果字符串 b b b 的首字符小于等于字符串 b b b 的尾字符,则规定字符串 b b b 大于字符串 a a a
代码
// 纯C语言
#include <stdio.h>
#include <stdlib.h> // qsort()
#include <string.h> // strcmp() 等
#define N 20// 字符串比较函数
int cmp(const void* a, const void* b) {const char* aa = (const char*)a;const char* bb = (const char*)b;int p = strlen(aa), q = strlen(bb);// 如果是前缀,则判断首尾字符的大小if (!strncmp(aa, bb, p) && bb[0] > bb[q - 1]) return 114514;if (!strncmp(bb, aa, q) && aa[0] > aa[p - 1]) return -114514;return strcmp(aa, bb);
}int main(void) {int n = 0, i = 0, j = 0, p = 0, q = 0;scanf("%d", &n);char s[n][N];for (i = 0; i < n; i++) {scanf("%s", s[i]);}qsort(s, sizeof(s) / sizeof(s[0]), sizeof(s[0]), cmp);for (i = n - 1; i >= 0; i--) {printf("%s", s[i]);}printf("\n");return 0;
}