题解 | #查找兄弟单词#

查找兄弟单词

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;
}

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务