[C字符串] 自己发明的模糊查找算法

事先申明:这是“图书馆模拟系统”大作业中的一个功能。此前还没学过KMP字符串匹配,就是按照自己掌握的东西,对需求进行分析写出来的东西,肯定还有很多可以优化的东西,有兴趣的同学可以和我留言讨论。

[C字符串] 自己发明的模糊查找算法_第1张图片

[C字符串] 自己发明的模糊查找算法_第2张图片

[C字符串] 自己发明的模糊查找算法_第3张图片

就这么个功能,昨晚回去后写到2点多,今早来又写了一个多小时,不断调试、更改,最终得到的效果还是差强人意的,蛮好蛮好

将该功能封装成C++的类:

#include 
using namespace std;
// Statement: 我们的模糊查找算法是建立在会写单词的基础上,对输入局部单词进行搜索 => 不包含单词检错的智能识别
// 先算出每本书的该模糊名的匹配度,然后将Books按照匹配度降序排序,依次询问是否查找此书
class Fuzzy {
public:
    int Number;
    char **Books;
    Fuzzy(char *pp[], int num) { this->Books = pp, this->Number = num; }
    void FuzzySearch() {
        printf("		                Input the fuzzy name of the book you want to find.\n\n");
        char sub[30];
        ReadStr(sub);
        int *match = Match(sub);
        for (int i = 0; i < Number; i++) {
            printf("match of Number %d = %d\n", i + 1, match[i]);
        }
//    双射 => 按照下标对应映射 => 在排match数组的时候完成对Books的匹配度降序排序
        for (int i = 0; i < Number - 1; i++) {
            for (int j = i + 1; j < Number; j++) {
                if (match[i] < match[j]) {
                    int Temp = match[i];
                    match[i] = match[j];
                    match[j] = Temp;
                    char *temp = Books[i];
                    Books[i] = Books[j];
                    Books[j] = temp;
                }
            }
        }
//    match == 0 终止 => 查无此书
        int flag = 0;
        for (int i = 0; i < Number; i++) {
            if (match[i] == 0) break;
            printf("		                Is '%s' the book you would find?(Y/N)\n\n", Books[i]);
            char Judge;
            scanf("%s", &Judge);
            getchar();
            if (Judge == 'Y' || Judge == 'y') {
                flag = 1;
                printf("		                Congratulations! You find the Book: ' %s ' successfully\n\n", Books[i]);
                break;
            }
        }
        if (!flag) printf("		                We would apologize that we can't find the book you want.\n\n");
    }

private:
    void ReadStr(char *book) {
        int k = 0;
        while((book[k] = getchar()) != '\n') k++;
        book[k] = '\0';
    }
    
    // 这里界定单词就是连续字母 => 以非字母为分界 => 功能:计算出单词数量 及 返回Initial Word
    int AnalyzeName(char *p, char **Initial) {
        char **pp = Initial;
        int flag = 0, cnt = 0;
        while(*p != '\0') {
            if(!isalpha(*p)) {
                flag = 0;
            }else if(flag == 0) {
                *pp = p, pp++;
                cnt++;
                flag = 1;
            }
            p++;
        }
        for(int i = 0; i < cnt - 1; i++) {
            char *temp = Initial[i];
            while(*temp != '\0') {
                if(!isalpha(*temp)) {
                    *temp = '\0';
                    break;
                }
                temp++;
            }
        }
        return cnt;
    }

//        p指向主串中与子串开始相同的位置 => 找出最合适的(最相似的)| 开始位置 main: (llo lu) sub:(lu)
    int CalculateSimilar(char *main, char *sub) {
        char *pm = main, *ps = sub, *temp;
        int MaxCount = 0;
        while(*pm != '\0') {
            int cnt = 0;
            temp = pm;
            while(*temp == *ps) {
                cnt++;
                temp++, ps++;
            }
//        重置 => 为下一次匹配做准备
            ps = sub;
            MaxCount = cnt > MaxCount ? cnt : MaxCount;
            pm++;
        }
        return MaxCount;
    }

// 计算子串单词数量 对每个单词首字母进行定位
    int* Match(char *name) {
        char **Initials = (char**)malloc(sizeof(char));
        int WordCnt = AnalyzeName(name, Initials);
        int *arr = (int*)malloc(sizeof(int) * Number);
//    我当时没有记录头指针 最后经过迭代传出去的是一个野指针
        int *pa = arr;
//    计算输入书名与每本书的书名匹配度
        for(int i = 0; i < Number; i++) {
            for(int j = 0; j < WordCnt; j++) {
                char *p = Books[i], *s = Initials[j];
                if(!j) *pa = CalculateSimilar(p, s);
                else *pa += CalculateSimilar(p, s);
            }
            pa++;
        }
        return arr;
    }

};

 最后大作业开源,供参考,也留个纪念

#include 
#include 
#include 
#include 

char* Books[50];
int Number;

void ReadStr(char *book);
void SortByAlpha();
int AnalyzeName(char *p, char **Initial);
int CalculateSimilar(char *main, char *sub);
int* Match(char *name);
int Menu();
void AddBook();
void ShowBook();
void PreciseSearch();
void FuzzySearch();
void ClearWindow();

int main() {
    int choice;
    Number = 0;
    while( (choice = Menu()) != 0 ) {
        switch (choice) {
            case 1:
                AddBook();
                break;
            case 2:
                ShowBook();
                break;
            case 3:
                PreciseSearch();
                break;
            case 4:
                FuzzySearch();
                break;
            case 5:
                ClearWindow();
                break;
            default:
                printf("Wrong Input!\n\n");
        }
    }
    return 0;
}

void ReadStr(char *book) {
    int k = 0;
    while((book[k] = getchar()) != '\n') k++;
    book[k] = '\0';
}

void SortByAlpha() {
    for(int i = 0; i < Number - 1; i++) {
        for(int j = i + 1; j < Number; j++) {
            if(strcmp(Books[i], Books[j]) > 0) {
                char *temp = Books[i];
                Books[i] = Books[j];
                Books[j] = temp;
            }
        }
    }
}

// 这里界定单词就是连续字母 => 以非字母为分界 => 功能:计算出单词数量 及 返回Initial Word
int AnalyzeName(char *p, char **Initial) {
    char **pp = Initial;
    int flag = 0, cnt = 0;
    while(*p != '\0') {
        if(!isalpha(*p)) {
            flag = 0;
        }else if(flag == 0) {
            *pp = p, pp++;
            cnt++;
            flag = 1;
        }
        p++;
    }
    for(int i = 0; i < cnt - 1; i++) {
        char *temp = Initial[i];
        while(*temp != '\0') {
            if(!isalpha(*temp)) {
                *temp = '\0';
                break;
            }
            temp++;
        }
    }
    return cnt;
}

//        p指向主串中与子串开始相同的位置 => 找出最合适的(最相似的)| 开始位置 main: (llo lu) sub:(lu)
int CalculateSimilar(char *main, char *sub) {
    char *pm = main, *ps = sub, *temp;
    int MaxCount = 0;
    while(*pm != '\0') {
        int cnt = 0;
        temp = pm;
        while(*temp == *ps) {
            cnt++;
            temp++, ps++;
        }
//        重置 => 为下一次匹配做准备
        ps = sub;
        MaxCount = cnt > MaxCount ? cnt : MaxCount;
        pm++;
    }
    return MaxCount;
}

// 计算子串单词数量 对每个单词首字母进行定位
int* Match(char *name) {
    char **Initials = (char**)malloc(sizeof(char));
    int WordCnt = AnalyzeName(name, Initials);
    int *arr = (int*)malloc(sizeof(int) * Number);
//    我当时没有记录头指针 最后经过迭代传出去的是一个野指针
    int *pa = arr;
//    计算输入书名与每本书的书名匹配度
    for(int i = 0; i < Number; i++) {
        for(int j = 0; j < WordCnt; j++) {
            char *p = Books[i], *s = Initials[j];
            if(!j) *pa = CalculateSimilar(p, s);
            else *pa += CalculateSimilar(p, s);
        }
        pa++;
    }
    return arr;
}

int Menu() {
    int choice;
    printf("	   ------------------------------Library Management System----------------------------------\n\n");
    printf("		                1.Add Book 			2.Show Book\n\n");
    printf("		                3.Precise Search	        4.Fuzzy Search\n\n");
    printf("		                5.Clear the window              0.Exit\n\n");
    printf("	   -----------------------------------------------------------------------------------------\n\n");
    printf("	   Please give your choice: ");
    scanf("%d", &choice);
    getchar();
    return choice;
}

// 这里在新增书籍信息后立即进行按字母顺序排序
void AddBook() {
    int n;
    printf("		                Please input the number of the books you want to add.\n\n");
    scanf("%d", &n);
    getchar();
    for(int i = Number; i < n; i++) {
        char *book = (char*)malloc(sizeof(char));
        printf("Input the name of the book:  ");
        ReadStr(book);
        Books[i] = book;
        Number++;
    }
    printf("		                All books you input are added over.\n\n");
    SortByAlpha();
}

void ShowBook() {
    if(!Number) {
        printf("\n\n		                Empty!\n\n");
        return;
    }
    for(int i = 0; i < Number; i++) {
        printf("		                %d. %s\n", i + 1, Books[i]);
    }
    printf("		                All books are on the screen.\n\n");
}

void PreciseSearch() {
    printf("		                Input the precise name of the book you want to find.\n\n");
    char name[30];
    ReadStr(name);
    int i;
    for(i = 0; i < Number; i++) {
        if(!strcmp(name, Books[i])) {
            printf("		                Number %d\n\n", i + 1);
            break;
        }
    }
    if(i == Number) printf("		                Not Found!\n\n");
}

// Statement: 我们的模糊查找算法是建立在会写单词的基础上,对输入局部单词进行搜索 => 不包含单词检错的智能识别 
// 先算出每本书的该模糊名的匹配度,然后将Books按照匹配度降序排序,依次询问是否查找此书
void FuzzySearch() {
    printf("		                Input the fuzzy name of the book you want to find.\n\n");
    char sub[30];
    ReadStr(sub);
    int *match = Match(sub);
    for(int i = 0; i < Number; i++) {
        printf("match of Number %d = %d\n", i + 1, match[i]);
    }
//    双射 => 按照下标对应映射 => 在排match数组的时候完成对Books的匹配度降序排序
    for(int i = 0; i < Number - 1; i++) {
        for(int j = i + 1; j < Number; j++) {
            if(match[i] < match[j]) {
                int Temp = match[i];
                match[i] = match[j];
                match[j] = Temp;
                char *temp = Books[i];
                Books[i] = Books[j];
                Books[j] = temp;
            }
        }
    }
//    match == 0 终止 => 查无此书
    int flag = 0;
    for(int i = 0; i < Number; i++) {
        if(match[i] == 0) break;
        printf("		                Is '%s' the book you would find?(Y/N)\n\n", Books[i]);
        char Judge;
        scanf("%s", &Judge);
        getchar();
        if(Judge == 'Y' || Judge == 'y') {
            flag = 1;
            printf("		                Congratulations! You find the Book: ' %s ' successfully\n\n", Books[i]);
            break;
        }
    }
    if(!flag) printf("		                We would apologize that we can't find the book you want.\n\n");
    SortByAlpha();
}

void ClearWindow() {
    system("cls");
}

你可能感兴趣的:(算法,c语言,开发语言)