题解 | #查找兄弟单词#
查找兄弟单词
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;
}


查看13道真题和解析