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