我必须进行字典模拟器的二进制搜索,现在这是我的功能,我不知道为什么它会崩溃,如果有人可以帮助我,我会很开心..! ^^
这是我的结构:
typedef struct
{
char *world;
char *meaning;
} par;
这里的代码不起作用。 我会为我的英语和变量的意大利名字感到抱歉,但我是意大利人...... ^^ 如果你需要一些建议,请告诉我..! 附: 我尽力评论,再次抱歉..!
#include <stdio.h>
#include <stdlib.h>
#define MAX 40
typedef struct
{
char *Parola;
char *Significato;
} par;
int Ricerca(par Dizionario[MAX][21], char Richiesta[20], int Min, int Max, int Iniziale);
int main()
{
par Dizionario[MAX][21] =
{
{
/////////////////////load my 2d array////////////////////
//seconda riga
{"Accendere", "Trasmettere energia elettrica a un apparecchio o dispositivo per farlo funzionare"},
{"Bellezza","Qualita' di ciò che è bello"},
{"Comune","Che e' di tutti, o che appartiene a piu' persone o cose"},
{NULL, NULL},
{"Elenco", "Nota, registro ordinato"},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
{"Impetuoso","Che si muove con impeto [anche in senso figurato]; che si lascia vincere dall'impeto"},
{"Lancio","Atto, effetto del lanciare o del lanciarsi"},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
{"Produrre","Presentare, allegare, citare"},
{NULL, NULL},
{NULL, NULL},
{"Saccone","Grosso sacco, imbottito generalmente di paglia, che si mette sotto il materasso o si usa talvolta in sua vece"},
{NULL, NULL},
{NULL, NULL},
{"Verticale","Perpendicolare a un piano orizzontale; che sta ritto con la parte superiore in alto e l'inferiore in basso"},
{NULL, NULL}
}
};
int i, j, flag, Iniziale = 0;
par temp;
char Richiesta[20], Rtemp[20];
/////////////////////bubble sort/////////////////////
for(j=0; j<21;j++)
{
for(i=0; i<MAX && Dizionario[i+1][j].Parola != NULL; i++)
{
if(strcmp(Dizionario[i][j].Parola, Dizionario[i+1][j].Parola) == 1)
{
temp=Dizionario[i][j];
Dizionario[i][j] = Dizionario[i+1][j];
Dizionario[i+1][j] = temp;
}
}
}
//i'm gonna ask to the user what word he want
printf("Che parola vuole cercare?");
gets (Richiesta);
strcpy(Rtemp, Richiesta);
printf("%s", Rtemp);
Rtemp[0] = toupper(Rtemp[0]);
printf("\n%s", Rtemp);
//I'm checking what's the first char, if it's a, i'm gonna assign 0 so it's
//it's gonna to the 'n' column and shifting there
switch(Rtemp[0])
{
case 'A': Iniziale = 0;
break;
case 'B': Iniziale = 1;
break;
case 'C': Iniziale = 2;
break;
case 'D': Iniziale = 3;
break;
case 'E': Iniziale = 4;
break;
case 'F': Iniziale = 5;
break;
case 'G': Iniziale = 6;
break;
case 'H': Iniziale = 7;
break;
case 'I': Iniziale = 8;
break;
case 'L': Iniziale = 9;
break;
case 'M': Iniziale = 10;
break;
case 'N': Iniziale = 11;
break;
case 'O': Iniziale = 12;
break;
case 'P': Iniziale = 13;
break;
case 'Q': Iniziale = 14;
break;
case 'R': Iniziale = 15;
break;
case 'S': Iniziale = 16;
break;
case 'T': Iniziale = 17;
break;
case 'U': Iniziale = 18;
break;
case 'V': Iniziale = 19;
break;
case 'Z': Iniziale = 20;
break;
}
flag = Search(Dizionario, Rtemp, 0, MAX, Iniziale);
printf("%d", flag);
system("PAUSE");
return 0;
}
int Search(par Dictionary[MAX][21], char Request[20], int Min, int Max, int init)
{
int Median;
Median = (Min+Max)/2;
if(strcmp(Request, Dizionario[Median][Init].world) == 0)
return Median;
else if(Max <= Min) // elemento non trovato
{
return -1;
}
else if(strcmp(Request, Dictionary[Median][Init].world)>= 1)
{
return Search(Dictionary, Request, Median+1, Max, Init);
printf("ok");
}else{
return Search(Dictionary, Request, Min, Median-1, Init);
printf("ok");
}
}
@ john3136 如果我要这样做(Iniziale = Rtemp [0] - 'A'),我可以知道我必须去哪里。 我解释得更好,rwason为什么这个转换是如果我有'A',我知道所有以'A'开头的世界都在posizion [x] [0] 对于B相同,但[x] [1]等等...我不知道我是否说出了我的观点,让我知道.. ^^ 附: 我也有问题&lt ;, ==或&gt;比0至少1 ..
@UliKöhler 他会在函数中崩溃,正如我通过调试所理解的那样,问题出在“strcmp()”调用中 特地在这里
if(strcmp(Request, Dizionario[Median][Init].world) == 0)
在这里
else if(strcmp(Request, Dictionary[Median][Init].world)>= 1)
@cnicutar 添加了null的控件,它崩溃了 我这样编辑了
if(strcmp(Richiesta, Dizionario[Mediano][Iniziale].Parola) == 0 && Dizionario[Mediano][Iniziale].Parola != NULL) // elemento trovato
if(strcmp(Richiesta, Dizionario[Mediano][Iniziale].Parola)> 0 && Dizionario[Mediano][Iniziale].Parola != NULL)
这些是我现在的2控制......
@BLUEPIXY 我不能使用bsearch,我必须自己使用二进制搜索...
答案 0 :(得分:1)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct {
char *Parola;
char *Significato;
} par;
par *Ricerca(par *Dizionario, char Richiesta[20], int num);
int main(){
par Dizionario[] = {
{"Accendere", "Trasmettere energia elettrica a un apparecchio o dispositivo per farlo funzionare"},
{"Bellezza","Qualita' di cio che e bello"},
{"Comune","Che e' di tutti, o che appartiene a piu' persone o cose"},
{"Elenco", "Nota, registro ordinato"},
{"Impetuoso","Che si muove con impeto [anche in senso figurato]; che si lascia vincere dall'impeto"},
{"Lancio","Atto, effetto del lanciare o del lanciarsi"},
{"Produrre","Presentare, allegare, citare"},
{"Saccone","Grosso sacco, imbottito generalmente di paglia, che si mette sotto il materasso o si usa talvolta in sua vece"},
{"Verticale","Perpendicolare a un piano orizzontale; che sta ritto con la parte superiore in alto e l'inferiore in basso"},
};
char Richiesta[20], Rtemp[20];
int numOfData = sizeof(Dizionario)/sizeof(*Dizionario);
par *temp;
printf("Che parola vuole cercare? :");
gets (Richiesta);
strcpy(Rtemp, Richiesta);
printf("%s\n", Rtemp);
Rtemp[0] = toupper(Rtemp[0]);
//printf("%s\n", Rtemp);
temp = Ricerca(Dizionario, Rtemp, numOfData);
if(temp != NULL)
printf("%s\n", temp->Significato);
else,
printf("not found\n");
system("PAUSE");
return 0;
}
int cmp(const void *a, const void *b){
const par *x = a;
const par *y = b;
return strcmp(x->Parola, y->Parola);
}
par *Ricerca(par *Dizionario, char Richiesta[20], int num){
par key = { Richiesta, NULL };
//replaced by the binary search function that your implements
return bsearch(&key, Dizionario, num, sizeof(key), cmp);
}
答案 1 :(得分:0)
经过大量的代码研究,我发现你正在尝试将字典组织成2D数组,这样你就可以从正确的第一个字母开始。不幸的是,这会使您的代码变得更加复杂 - 并且会导致致命的错误。
例如,在行
中if(strcmp(Request, Dictionary[Median][init].word) == 0)
您正在访问可能从未初始化的字典元素的元素.word
- 事实上,因为每个字母的字母只有一个条目,并且您硬编码MAX
,它是一个肯定。所以你发现自己有一个空指针 - 不是一个好的字符串来比较。您必须知道每行数据的长度。要想出来,你的二进制搜索需要从搜索字典的结尾开始。这导致以下(工作)代码:
include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 40
typedef struct
{
char *word;
char *meaning;
} par;
int Ricerca(par Dizionario[MAX][21], char Richiesta[20], int Min, int Max, int Iniziale, int depth);
int main()
{
par Dizionario[MAX][21] =
{
{
/////////////////////load my 2d array////////////////////
//seconda riga
{"Accendere", "Trasmettere energia elettrica a un apparecchio o dispositivo per farlo funzionare"},
{"Bellezza","Qualita' di ciò che è bello"},
{"Comune","Che e' di tutti, o che appartiene a piu' persone o cose"},
{NULL, NULL},
{"Elenco", "Nota, registro ordinato"},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
{"Impetuoso","Che si muove con impeto [anche in senso figurato]; che si lascia vincere dall'impeto"},
{"Lancio","Atto, effetto del lanciare o del lanciarsi"},
{NULL, NULL},
{NULL, NULL},
{NULL, NULL},
{"Produrre","Presentare, allegare, citare"},
{NULL, NULL},
{NULL, NULL},
{"Saccone","Grosso sacco, imbottito generalmente di paglia, che si mette sotto il materasso o si usa talvolta in sua vece"},
{NULL, NULL},
{NULL, NULL},
{"Verticale","Perpendicolare a un piano orizzontale; che sta ritto con la parte superiore in alto e l'inferiore in basso"},
{NULL, NULL}
}
};
int i, j, flag, Iniziale = 0;
par temp;
char Richiesta[20], Rtemp[20];
/////////////////////bubble sort/////////////////////
printf("unsorted array:\n");
for(j=0; j<21;j++)
{
if (Dizionario[0][j].word != NULL) printf("%d: %s\n", j, Dizionario[0][j].word);
for(i=0; i<MAX && Dizionario[i+1][j].word != NULL; i++)
{
if(strcmp(Dizionario[i][j].word, Dizionario[i+1][j].word) < 0)
{
temp=Dizionario[i][j];
Dizionario[i][j] = Dizionario[i+1][j];
Dizionario[i+1][j] = temp;
}
}
}
//i'm gonna ask to the user what word he want
printf("Che parola vuole cercare?\n");
fgets (Richiesta, sizeof(Richiesta)-1, stdin);
strncpy(Rtemp, Richiesta, strlen(Richiesta)-1); // do not copy newline
Rtemp[0] = toupper(Rtemp[0]);
printf("\nLooking for '%s'\n", Rtemp);
//I'm checking what's the first char, if it's a, i'm gonna assign 0 so it's
//it's gonna to the 'n' column and shifting there
// changed from lengthy switch() to more compact array:
char firstLetter[] = {0,1,2,3,4,5,6,7,8,-1,-1,9,10,11,12,13,14,15,16,17,18,19,-1,-1,-1,20};
Iniziale = firstLetter[Rtemp[0] - 'A'];
#if 0
switch(Rtemp[0])
{
case 'A': Iniziale = 0;
break;
case 'B': Iniziale = 1;
break;
case 'C': Iniziale = 2;
break;
case 'D': Iniziale = 3;
break;
case 'E': Iniziale = 4;
break;
case 'F': Iniziale = 5;
break;
case 'G': Iniziale = 6;
break;
case 'H': Iniziale = 7;
break;
case 'I': Iniziale = 8;
break;
case 'L': Iniziale = 9;
break;
case 'M': Iniziale = 10;
break;
case 'N': Iniziale = 11;
break;
case 'O': Iniziale = 12;
break;
case 'P': Iniziale = 13;
break;
case 'Q': Iniziale = 14;
break;
case 'R': Iniziale = 15;
break;
case 'S': Iniziale = 16;
break;
case 'T': Iniziale = 17;
break;
case 'U': Iniziale = 18;
break;
case 'V': Iniziale = 19;
break;
case 'Z': Iniziale = 20;
break;
}
#endif
if (Iniziale == -1) {
printf("no word with that first letter!\n");
return 0;
}
printf("Iniziale = %d\n", Iniziale);
flag = Search(Dizionario, Rtemp, 0, MAX, Iniziale, 0);
printf("result of search was flag = %d\n", flag);
//system("PAUSE");
return 0;
}
int Search(par Dictionary[MAX][21], char Request[20], int Min, int Max, int init, int depth)
{
int Median;
Median = (Min+Max)/2;
//printf("calling Search with min =%d, max = %d, median = %d, depth = %d\n", Min, Max, Median, depth);
depth++;
if (depth > 10) return 0; // trap an infinite loop - with MAX of 40, binary search should take only 6 iterations
par *temp;
if(Max <= Min) // elemento non trovato
{
printf("element not found!\n");
return -1;
}
if(Dictionary[Median][init].word==NULL) {
// out of bounds in the dictionary
return Search(Dictionary, Request, Min, Median, init, depth);
}
if(strcmp(Dictionary[Median][init].word, Request) == 0) {
printf("Word was found!\nDefinition = %s\n", Dictionary[Median][init].meaning);
return 1;
}
if(strcmp(Request, Dictionary[Median][init].word) > 0 )
{
return Search(Dictionary, Request, Median+1, Max, init, depth);
} else {
return Search(Dictionary, Request, Min, Median-1, init, depth);
}
}
我做了很多改变!为了帮助您弄清楚我做了什么,这里是原始代码和最终编译的代码之间的diff
。注意 - 我用一对switch
... #if 0
语句包围了你的巨大#endif
语句;并用数组替换它们。这实际上并没有“破坏”(除了缺少default
声明),但仍然非常难看。我相信您知道如何阅读diff
- >
表示“添加了某些内容”,<
表示“删除了某些内容”。
我略微更改了Search
的签名,包括depth
因素。事实证明,您的分段错误是通过对Search
函数的64k递归调用来调用的......在调试期间我添加了此参数以查看早期迭代中发生的情况。
现在看看这是否有意义。
2a3
> #include <string.h>
7,8c8,9
< char *Parola;
< char *Significato;
---
> char *word;
> char *meaning;
11c12
< int Ricerca(par Dizionario[MAX][21], char Richiesta[20], int Min, int Max, int Iniziale);
---
> int Ricerca(par Dizionario[MAX][21], char Richiesta[20], int Min, int Max, int Iniziale, int depth);
49a51
> printf("unsorted array:\n");
52c54,55
< for(i=0; i<MAX && Dizionario[i+1][j].Parola != NULL; i++)
---
> if (Dizionario[0][j].word != NULL) printf("%d: %s\n", j, Dizionario[0][j].word);
> for(i=0; i<MAX && Dizionario[i+1][j].word != NULL; i++)
54c57
< if(strcmp(Dizionario[i][j].Parola, Dizionario[i+1][j].Parola) == 1)
---
> if(strcmp(Dizionario[i][j].word, Dizionario[i+1][j].word) < 0)
61a65
>
63,66c67,69
< printf("Che parola vuole cercare?");
< gets (Richiesta);
< strcpy(Rtemp, Richiesta);
< printf("%s", Rtemp);
---
> printf("Che parola vuole cercare?\n");
> fgets (Richiesta, sizeof(Richiesta)-1, stdin);
> strncpy(Rtemp, Richiesta, strlen(Richiesta)-1); // do not copy newline
68c71
< printf("\n%s", Rtemp);
---
> printf("\nLooking for '%s'\n", Rtemp);
70a74,77
> // changed from lengthy switch() to more compact array:
> char firstLetter[] = {0,1,2,3,4,5,6,7,8,-1,-1,9,10,11,12,13,14,15,16,17,18,19,-1,-1,-1,20};
> Iniziale = firstLetter[Rtemp[0] - 'A'];
> #if 0
116,119c123,132
< flag = Search(Dizionario, Rtemp, 0, MAX, Iniziale);
< printf("%d", flag);
<
< system("PAUSE");
---
> #endif
> if (Iniziale == -1) {
> printf("no word with that first letter!\n");
> return 0;
> }
> printf("Iniziale = %d\n", Iniziale);
> flag = Search(Dizionario, Rtemp, 0, MAX, Iniziale, 0);
> printf("result of search was flag = %d\n", flag);
>
> //system("PAUSE");
122c135
< int Search(par Dictionary[MAX][21], char Request[20], int Min, int Max, int init)
---
> int Search(par Dictionary[MAX][21], char Request[20], int Min, int Max, int init, int depth)
125a139,142
> //printf("calling Search with min =%d, max = %d, median = %d, depth = %d\n", Min, Max, Median, depth);
> depth++;
> if (depth > 10) return 0; // trap an infinite loop - with MAX of 40, binary search should take only 6 iterations
> par *temp;
127,129c144
< if(strcmp(Request, Dizionario[Median][Init].world) == 0)
< return Median;
< else if(Max <= Min) // elemento non trovato
---
> if(Max <= Min) // elemento non trovato
130a146
> printf("element not found!\n");
134c150,159
< else if(strcmp(Request, Dictionary[Median][Init].world)>= 1)
---
> if(Dictionary[Median][init].word==NULL) {
> // out of bounds in the dictionary
> return Search(Dictionary, Request, Min, Median, init, depth);
> }
> if(strcmp(Dictionary[Median][init].word, Request) == 0) {
> printf("Word was found!\nDefinition = %s\n", Dictionary[Median][init].meaning);
> return 1;
> }
>
> if(strcmp(Request, Dictionary[Median][init].word) > 0 )
136,140c161,163
< return Search(Dictionary, Request, Median+1, Max, Init);
< printf("ok");
< }else{
< return Search(Dictionary, Request, Min, Median-1, Init);
< printf("ok");
---
> return Search(Dictionary, Request, Median+1, Max, init, depth);
> } else {
> return Search(Dictionary, Request, Min, Median-1, init, depth);