-题目
char ** reorderLogFiles(char ** logs, int logsSize, int* returnSize){
}
-解题思路
把字母日志全部排在数字日志前,利用快排的性质,使用strcmp函数分别排列字母日志,数字日志。
知识点-
解答这道问题,最好先熟悉以下四个函数:
1. 函数isdigit:
功能 - 判断参数是否为数字,为数字返回非0,不为数字返回0。
头文件 - <ctype.h>
函数声明 - int isdigit(int c);
范例 -
2. 函数strstr:
功能 - 找到子串在一个字符串中第一次出现的位置。
头文件 - <string.h>
函数声明 - char *strstr(const char *str1, const char *str2);
范例 -
3. 函数strcmp:
功能 - 根据ascii码比较两个字符串的大小
头文件 - <string.h>
函数声明 - int strcmp(char *str1,char *str2);
从第一个字符开始比较,如果到最后两个字符串完全相同,则strcmp()函数输出的值为0;若开始出现不同的字符,根据这个字符ascii码进行比较,若str1的ascii值大于str2则输出值大于 0;反之,输出值小于 0;
4. 函数qsort:
功能 - 排序函数
头文件 - <stdlib.h>
函数声明 - void qsort (void* base, size_t num, size_t size,int (*compar)(const void*,const void*));
共四个参数 第一个参数 首元素地址base;第二个参数 元素个数num;第三个参数 元素大小size;第四个参数 自定义比较函数compar
qsort函数给cmp函数规定了特定的参数。因此我们设计cmp函数时要严格遵守其参数设定。
int compar (const void* e1, const void* e2);
compar参数是qsort函数排序的核心内容,它指向一个比较两个元素的函数,注意两个形参必须是const void *型,同时在调用compar 函数(compar实质为函数指针,这里称它所指向的函数也为compar)时,传入的实参也必须转换成const void *型。在compar函数内部会将const void *型转换成实际类型。
若compar返回负值,e1所指的元素会排在e2前面;返回0,e1与e2的值不确定;返回正值,e2排在e1前面。
如果两个元素的值是相同的,那么它们的前后顺序是不确定的。也就是说qsort()是一个不稳定的排序算法。
范例 -
由上面几个函数可知,每个字符串先用strstr函数找到第一个空格,分开字母日志与数字日志,在compare函数里将其分别排序。注意这题要求数字日志需要保持原来的相对顺序,但是快排具有不稳定性,这就需要利用结构体给每个字符串一个“下标”,用来排序数字日志。
代码部分
struct Pair {
char * log;
int idx;
};
int logCompare(const void *log1, const void *log2) {
char *s1 = ((struct Pair *)log1)->log;
char *s2 = ((struct Pair *)log2)->log;
char *split1 = strstr(s1, " ");
char *split2 = strstr(s2, " ");
bool isDigit1 = isdigit(split1[1]);
bool isDigit2 = isdigit(split2[1]);
if (isDigit1 && isDigit2) {
return ((struct Pair *)log1)->idx - ((struct Pair *)log2)->idx;
}
if (!isDigit1 && !isDigit2) {
int sc = strcmp(split1, split2);
if (sc != 0) {
return sc;
}
return strcmp(s1, s2);
}
return isDigit1 ? 1 : -1;
}
char ** reorderLogFiles(char ** logs, int logsSize, int* returnSize){
struct Pair * arr = (struct Pair *)malloc(sizeof(struct Pair) * logsSize);
for (int i = 0; i < logsSize; i++) {
arr[i].log = logs[i];
arr[i].idx = i;
}
qsort(arr, logsSize, sizeof(struct Pair), logCompare);
char ** ans = (char **)malloc(sizeof(char *) * logsSize);
for (int i = 0; i < logsSize; i++) {
ans[i] = arr[i].log;
}
*returnSize = logsSize;
free(arr);
return ans;
}