> 分析
>> 本题的难点在于排序速度上
>> 排序算法要考虑重复项很多,无重复项两种情况
>> 当然由于本题对内存占用的要求不高,也可以不使用排序
> 总体思路
>> 先将电话号码按输入的顺序存下来
>> 对所有号码使用堆排序
>> 排序后根据号码连续出现的频率输出频率大于1的号码
> 输入转换
>> 本题中已详细定义了字母到数字的映射,因此推荐使用映射表较快
> 存储形式
>> 由于涉及到排序比较,因此推荐电话号码以整型存储,不使用字符串
> 排序
>> 考虑到可能出现很多重复的号码,因此推荐使用堆排序
>> 快速排序在处理重复项过多时效率脚底
> 附代码
/*--------------------------------- * 堆排序,输出时计算出现频率 *---------------------------------*/ #include "stdio.h" #include "string.h" #include "stdlib.h" /* 字母到数字的映射表 */ const int map[26] = { 2, 2, 2, /* A, B, C */ 3, 3, 3, /* D, E, F */ 4, 4, 4, /* G, H, I */ 5, 5, 5, /* J, K, L */ 6, 6, 6, /* M, N, O */ 7, 0, 7, 7, /* P, Q, R, S */ 8, 8, 8, /* T, U, V */ 9, 9, 9, /* W, X, Y */ 0 /* Z */ } ; /* 存储出现的所有电话号码 */ int teleNum[100000] = {0} ; void exchange(int *p1, int *p2) { int tmp = *p1 ; *p1 = *p2 ; *p2 = tmp ; } /* 保持最大堆的性质(非递归) */ void maxHeapify(int *pStart, int size, int i) { int left = 0 ; int right = 0 ; int largest = 0 ; largest = i ; do { i = largest ; left = 2 * i + 1 ; right = 2 * i + 2 ; if(left < size && pStart[left] > pStart[largest]) largest = left ; if(right < size && pStart[right] > pStart[largest]) largest = right ; if(largest != i) exchange(&pStart[i], &pStart[largest]) ; }while(largest != i) ; } /* 堆排序 */ void sort(int *pStart, int size) { int i = 0 ; for(i = size/2 - 1; i >= 0; i--) maxHeapify(pStart, size, i) ; for(i = size - 1; i > 0; i--) { exchange(&pStart[0], &pStart[i]) ; maxHeapify(pStart, i, 0) ; } } int main(void) { int n = 0 ; char s[50] = {0} ; int num = 0 ; int i = 0, j = 0 ; int count = 0 ; char flag = 0 ; scanf("%d", &n) ; for(i = 0; i < n; i++) { memset(s, 0, sizeof(s)) ; scanf("%s", s) ; /* 将电话号码转换为整型 */ num = 0 ; for(j = 0; j < sizeof(s); j++) { if(0 == s[j]) break ; if(‘Q‘ == s[j] || ‘Z‘ == s[j]) continue ; if(s[j] >= ‘A‘ && s[j] <= ‘Z‘) num = num * 10 + map[s[j] - ‘A‘] ; if(s[j] >= ‘0‘ && s[j] <= ‘9‘) num = num * 10 + s[j] - ‘0‘ ; } teleNum[i] = num ; } sort(teleNum, n) ; flag = 0 ; num = teleNum[0] ; count = 1 ; for(i = 1; i < n; i++) { if(teleNum[i] != num) { if(count > 1) { flag = 1 ; printf("%03d-%04d %d\r\n", num / 10000, num % 10000, count) ; } num = teleNum[i] ; count = 1; } else count++ ; } if(count > 1) { flag = 1 ; printf("%03d-%04d %d\r\n", num / 10000, num % 10000, count) ; } if(0 == flag) printf("No duplicates.\r\n") ; return 0 ; }
时间: 2024-11-08 02:33:33