题解 | #查找兄弟单词#
查找兄弟单词
https://www.nowcoder.com/practice/03ba8aeeef73400ca7a37a5f3370fe68
//HJ27 查找兄弟单词 #include <stdio.h> #include <string.h> #include <stdlib.h> int* FreqofOccur(char* str) { int* arr; int n = 26; arr = (int*)malloc(n * sizeof(int)); //int n=sizeof(arr)/sizeof(int);这样的话永远只是拿数组指针的8字节除以int的4字节; for (int i = 0; i < n; i++) { arr[i] = 0; char* searchbegin = str; while ((searchbegin = strchr(searchbegin, (char)(i + 97))) != NULL) { arr[i]++; searchbegin++; } } return arr; } int IsBroWord(char* initWrd, char* testWrd, int* inittimes) { int length = strlen(initWrd); if (strlen(testWrd) == length) { if (strncmp(initWrd, testWrd, length) != 0) { //题目未指明是否会输入大写字符,这里先只收集小写字符出现频次 //将两个单词的字母出现频次比对 int* testtimes = FreqofOccur( testWrd); //initWrd的出现次数不要每次都统计一边,数组指针作为参数传进来吧 //比较两个数组 int checknum = memcmp(inittimes, testtimes, sizeof(int)*26); free(testtimes); if (checknum != 0) { return 0; } else { return 1; } } else return 0; } return 0; } int cmp(char* a, char* b, int la, int lb) { //先获取两方较小的字符串长度 //int la=strlen(a); //int lb=strlen(b); int leng = la < lb ? la : lb; switch (strncmp(a, b, leng)) { case 0: if (la == lb) return 0; else if (lb > la) { return -1; } else return 1; break; case 1: return 1; break; case -1: return -1; break; default: break; } return 0; } int main() { int dictnum = 0; scanf("%d", &dictnum); char** dict = (char**)malloc(dictnum * sizeof(char*)); //不能先验证,因为输入是把所有的字典单词先输入在输入基准单词,所以只能保存整个字典 for (int i = 0; i < dictnum; i++) { char tmp[10]; scanf("%s", tmp); int wdleth = strlen(tmp); dict[i] = (char*)malloc(wdleth * sizeof( char)); //其实这样申请的空间少了一个,但是因为实际申请是会有空余的,所以不需要担心结束符超出//还是要担心的,因为后面free的时候会找不到结束符 strncpy(dict[i], tmp, wdleth + 1); //错误点1:记得要把结束符也复制过来 } char initwd[10]; scanf("%s", initwd); int k = 0; scanf("%d", &k); int* inittimes = FreqofOccur(initwd); // //两种思路,1直接先对字典排序,然后从头开始找到符合兄弟单词的第k个; // 2对字典中是兄弟单词的进行挑选,保存至新数组后排序,找newarr[k-1] //法一,还是自己写个循环吧 for (int i = 0; i < dictnum; i++) { int li = strlen(dict[i]); for (int j = i + 1; j < dictnum; j++) { int lj = strlen(dict[j]); if (cmp(dict[i], dict[j], li, lj) > 0) { char tmp[lj + 1]; strncpy(tmp, dict[j], lj + 1); //不行,这样子的话dict[i]与dict[j]申请的空间不一致,要free掉再申请 free(dict[j]); dict[j] = (char*)malloc(li * sizeof(char)); strncpy(dict[j], dict[i], li + 1); free(dict[i]); dict[i] = (char*)malloc(lj * sizeof(char)); strncpy(dict[i], tmp, lj + 1); li = strlen(dict[i]); } } } //上面对dict排序结束 //使用兄弟验证 int findbro = 0; char* kthwd; for (int i = 0; i < dictnum; i++) { if (IsBroWord(initwd,dict[i], inittimes) == 1) { findbro++; if (findbro == k) { kthwd = dict[i]; } } } printf("%d\n", findbro); if(findbro>=k) { printf("%s",kthwd); } return 0; }