• ベストアンサー

ハッシュ法の質問

#include <stdlib.h> #include <stdio.h> #include <string.h> #define M 257 int zoo(char *v){ int x; x=0; while(*v) x = 256*x + (*v++); if (x<0) x=(-x); return(x%M);} #define CHARMAX 10000 static int chartop=0; static int charbtm=CHARMAX; static char charheap[CHARMAX]; char *goo(char *s){ char *cp; int i,j,len,result; cp =s; len=0; while(*cp++) len++; len++; if(charbtm - chartop < len){ printf("errrrrrrrrrrrrrrrrrrrr"); exit(1);} result = chartop; j=chartop; chartop += len; cp=s; for (i=0;i<len;i++) charheap[j+i]=(*cp++); return(&charheap[result]);} struct item {char *id; int info;}; static struct item table[M]; void initialize(){ int i; for(i=0; i<M; i++){ table[i].id=goo(" ");}} void enter(char *id1, int info1){ int x; x=zoo(id1); while(strcmp(table[x].id, " ")) x=(x+1)%M; table[x].id =goo(id1); table[x].info=info1;} int search(char *id1){ int x; x=zoo(id1); while(strcmp(table[x].id,id1)) x=(x+1)%M; return(table[x].info);} main(){ int t; initialize(); enter("takahasi",1234); enter("kato",2345); enter("saito",4532); printf("%d\n",search("takahasi")); printf("%d\n",search("kato")); printf("%d\n",search("saito")); } これは学生の学籍番号を登録し、登録した名前から番号を検索するプログラムです。 1.このプログラムでは何人まで登録できますか? 2.その人数を超えた場合何が起こるか。 3.配列charheap、配列tableには何が格納されているか という問題があたのですが上の3つの問題がわかりません。誰か教えてください。1・は10000かなっておもいましたが違うようです。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

1.不明 →格納できる配列の大きさはソース中に記されているが、 →それ以外の要素による制限がある。 →「それ以外の要素」は入力に依存するため、 →結果として「不明」である。 →※1人38文字未満なら「ソース中に記されている」人 →※10000 / 「ソース中に記されている」 = 38.9 2. →while(strcmp(table[x].id, " ")) x=(x+1)%M; →xがとりうる範囲と、そのときの挙動は? 3. →char *goo()とvoid enter()関数が →何をしているか追いかければわかります。

その他の回答 (2)

  • ymmasayan
  • ベストアンサー率30% (2593/8599)
回答No.2

ヒントのみ。 関数zoo・・・ハッシュ計算 関数*goo・・・氏名蓄積処理 関数initialize・・・初期化 関数enter・・・ハッシュ表への登録 関数search・・・ハッシュ表の検索 1,2は判りやすいですが、3は関数*gooとのからみが若干難しいので 少し悩んでください。 がんばってください。

回答No.1

答はすべてコードの中に'明快に'記されています。

関連するQ&A

  • ハッシュ法が得意な人お願いします。

    辞書検索プログラムが実行できません。どこがおかしいか教えてください。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define BUCKET_SIZE 100 typedef struct pointer { struct cell *chain; }pointer; struct cell{ char eng[20]; char jp[40]; struct cell *next; } table[BUCKET_SIZE]; int n; void read_dic(); void init_table(); int hash(char *tango); void main(); struct cell *find(char *tango); struct pointer bucket[BUCKET_SIZE]; void init_table() { int i; for (i=0;i<BUCKET_SIZE;i++){ strcpy(table[i].eng,"0"); strcpy(table[i].jp,"0"); } } void main() { int m; struct cell *p; char tango[20]; read_dic(); while(1){ printf("\n単語を入力: "); scanf("%s", tango); if (strcmp(tango, "*") == 0){ printf("検索を終了\n"); exit(0); } if((p= find(tango)) == NULL) printf("単語は見つかりませんでした\n"); else printf("訳語: %s \n", table[p].jp); } } まだ続きます。。。

  • シーザー暗号(C言語)

    シーザー暗号というものを作ろうとしていますが、文字のずらし方がわからず詰まっています。 手順は一応考えてあります。 (1)入力された文字を配列input[301]に代入 (2)何文字ずらすかを指定してその数値を変数countに代入 (3)入力された文字の長さを変数lenに代入 (4)inputとcountとlenを、文字をずらしてそれをoutputに返す関数shiftに渡す (5)outputを表示する のような感じですが、肝心の文字のずらし方がわかりません。 JISコードを使ってやるといいと聞いたんですが、そのやり方がわかりません。 ソース↓ #include <stdio.h> #include <string.h> int shift_char(char x[], int y, int z) { int i; for(i = 0; i <= z; i++) { x[i] = x[i] + y; } return x; } int main(int argc, char* argv[]) { char input[301]; char output[301]; int count, len, i; printf("文字を入力してください: "); scanf("%s" ,input); printf("何文字ずらしますか: "); scanf("%d" ,count); len = strlen(input); output = shift_char(input, count, len); for(i = 0; i <= len; i++) { printf("%s" ,output[i]); } return 0; } よろしくお願いします。

  • プログラミング教えてください!!!お願いします。

    プログラミング教えてください!!!お願いします。 次の文が実行されると何がどのようにプリントされるか。何もプリントされない時は「なし」と記せ。 また、途中に「ブランク」が入る場合は、”b”と記せ。 (1) int func1(), func2(); int data = 100; main() { int w = 1; static x =10; printf("** %d, %d, %d\n" ,w,x,data); func1(); printf("** %d, %d, %d\n" ,w,x,data); } int func1(){ int w = 2; static int x = 20: printf("*** %d, %d, %d\n", w, x, data); x += 10; func2(); printf("*** %d, %d, %d\n" , w,x,data); x *= 2; data = data - x; } int func2() { int w = 3; static int x = 30; printf("**** %d, %d, %d\n" ,w,x,data); data -= x; } (2) int func1(char *, char *, char *); int func2(char *, char *, char *); main() { char sta[20], stb[20], stc[20], std[20]; int i=0; func1("abc","xyz",sta); printf("%d -- %s\n" ,++i,sta); func1("123","456",stb); printf("%d -- %s\n" ,++i,stb); func1(sta,stb,stc); printf("%d -- %s\n" ,++i,stc); func2(sta,stb,std); printf("%d -- %s\n" ,++i,std); } int func1(char *a, char *b, char *c){ while(*a) *c++ = *a++; while(*b) *c++ = *b++; * c = 0x00; } int func2(char *a, char *b, char *c){ int i = 0; while(*b){ if(i%2 == 0) *c++ = *a++; else *c++ = *b++; i++; } *c = 0x00; }

  • 構造体内のポインタのポインタについて

    ポインタを理解するために以下のようなテストプログラムを作りました。 test.h --- typedef struct i_info{ int i_id; char i_name[64]; } I_INFO; typedef struct j_info{ int j_id; char j_name[64]; } J_INFO; typedef struct k_info{ int k_id; char k_name[64]; } K_INFO; typedef struct info{ int id; char name[64]; I_INFO iinfo; J_INFO *jinfo; K_INFO **kinfo; } INFO; --- test.c --- 1 #include <stdlib.h> 2 #include <stdio.h> 3 #include "./test.h" 4 5 int main(int argc, char **argv) 6 { 7 INFO info; 8 J_INFO j; 9 K_INFO k; 10 K_INFO *pk=NULL; 11 12 memset (&info,NULL,sizeof(info)); 13 memset (&j,NULL,sizeof(j)); 14 memset (&k,NULL,sizeof(k)); 15 16 info.id = 1; 17 memcpy(info.name,"***",3); 18 19 info.iinfo.i_id = 2; 20 memcpy(info.iinfo.i_name,"*i*",3); 21 22 info.jinfo = &j; 23 j.j_id = 3; 24 memcpy(j.j_name,"*j*",3); 25 26 info.kinfo = &pk; 27 pk= &k; 28 k.k_id = 4; 29 memcpy(k.k_name,"*k*",3); 30 31 printf( "%d\n",info.id); 32 printf( "%s\n",info.name); 33 printf( "%d\n",info.iinfo.i_id); 34 printf( "%s\n",info.iinfo.i_name); 35 printf( "%d\n",info.jinfo->j_id); 36 printf( "%s\n",info.jinfo->j_name); 37 /* 38 printf( "%d\n",info.kinfo->k_id); 39 printf( "%s\n",info.kinfo->k_name); 40 */ 41 } --- 38,39行目をコメントアウトするとコンパイルは通るのですが、 そのままだとコンパイルエラーになります。 なぜいけないのでしょうか?理由を教えてください。

  • 処理系によって。

    プログラムの作成をしたのですが、 自宅(VisualC++)だと実行できるのに、 学校の端末(OSしかわかりませんが、UNIXです。) だと、core dumpedしてしまいます。 どういう原因が考えられるでしょうか? プログラムソースは次の通りです。 ―――――――――――――――――――――――――― #include<stdio.h> #include<stdlib.h> char *strtok(char *moji, char cc); void main() { char moji[200]; char kugiri[10]; char *cp; printf("文字列を入力してください\n"); scanf("%s",moji); printf("区切り文字を入力してください\n"); scanf("%s",kugiri); cp=strtok(moji,kugiri[0]); printf("取り出した文字列は%s\n",cp); while(cp!=NULL){ cp=strtok(NULL,kugiri[0]); printf("取り出した文字列は%s\n",cp); } } char *strtok(char *moji,char cc) { int len; char *cp1,*cp2; char *mem; static char *moji_old; if(moji==NULL){ moji=moji_old; }      len=0; cp1=moji; while(*cp1!='\0'){ len++; cp1++; } mem=malloc(len+3); if(mem==NULL){ puts("メモリが足りません\n"); return NULL; } cp1=moji; cp2=mem; while(*cp1!=cc && *cp1!='\0'){ *cp2=*cp1; cp1++; cp2++; } free(mem); if(*cp1=='\0'){ moji_old=cp1; mem=NULL; } else{ moji_old=cp1+1; *cp2='\0'; } return mem; } ―――――――――――――――――――――――――― 以上です。

  • ボイヤームーア法について

    課題が分からなくて困っています。課題の内容は「ボイヤームーア法を用いてファイルの先頭からテキストを1行ずつ(1行の文字数は999文字以下とする)読み込み、何行目の何文字目に探索文字列の先頭が存在するか出力するプログラムを作成せよ。探索文字列中に同じ文字が含まれる場合については探索方法を改良せよ」というものです。1行の文字列を探索するプログラムは作れたのですが、複数の行を読み込んで何行目の何文字目かを出力させる方法がどうしてもわかりません。無知な私ですがどうかよろしくお願いします。締め切りは明日なのでなるべく早くお願いします。 #include<stdio.h> #include<string.h> #define MAX1 1000 #define MAX2 256 int bm(char txt[MAX1], char pat[MAX2]) { int a,b,len1,len2,skip[MAX2+1]; len1=strlen(txt); len2=strlen(pat); for(a=0;a<=MAX2;a++){ skip[a]=len2; } for(a=0;a<len2-1;a++){ skip[pat[a]] = len2-a-1; } while(a<len1){  b=len2-1;   while(txt[a]==pat[b]){    if(b==0){ return(a);    }    b--;    a--;   }   a+=skip[txt[a]]; } return(-1); } int main(void) { int x; char filename[MAX2],ex[MAX1],strg[MAX2]; FILE *fp; printf("Input filename:"); scanf("%s",filename); getchar(); fp=fopen(filename,"r"); if(fp == NULL){ printf("read open error!\n"); return(-1); } printf("Input search string:"); scanf("%s",strg); getchar(); for(i=0;i<MAX1;i++){    if(feof(fp)){   break;  } fgets(ex[i],MAXCHR1,fp); } x=bm(ex,strg); if(x==-1){  printf("There is not pattern in the text"); } else{  printf("%s%d\n",strg,x+1); } fclose(fp); return 0; }

  • ポインタと出力について

    現在C言語を勉強している者ですが、参考書をもとに自分でソースコードを書いて少し疑問に思った所がありました。以下がそのソースコードです。 #include <stdio.h> int main(void) { int dt = 0x41424344; int *ip; char *cp; ip = &dt; cp = (char *)ip; printf("%x\n", *ip); printf("%x\n", *cp); printf("%x\n", *cp++); printf("%x\n", *cp++); printf("%x\n", *cp++); return 0; } 出力結果は 41424344 44 44 43 42 となります。 私の予想していた結果は 41424344 44 43 42 41 でしたが、結果はなぜか44が二回出力されています。 2番目のprintf("%x\n", *cp); と 3番目のprintf("%x\n", *cp++);は明らかに3番目のprintfが *cp++ で番地が1つ進んでいると思うのですが結果を見る限りでは同じ数字44が出力されています。なぜこうなってしまうのでしょうか? 説明不足でしたらまた追加しますのでどうかよろしくおねがいします。  

  • strcmp

    超C言語初心者です。strcmpを使わずに文字列を比較する文を書いているのですが、途中でわからなくなりました。 宜しければご指摘お願いします。 #include<stdio.h> int main(){ char cp1[100],char2[100]; int i=0; int j=0 printf("1つ目の文字列:\n"); scanf("%s\n",cp1); printf("2つ目の文字列:\n"); scanf("%s\n",cp2); while(cp1[i]=='\0' || cp2[j]=='\0'||cp1[i]==cp2[j]=='\0'){ cp1[i++]; cp2[j++]; } if(cp[i]==cp2[j]=='\0'){ printf("同じ文字数\n); }else if (cp1[i]=='\0'&&cp2[j]!='\0'){ printf("2つ目の方が大きい\n); }else if (cp2[j]=='\0'&&cp1[i]!='\0'){ printf("1つ目の方が大きい\n); } exit(0); } と今書いています。間違いだらけでしょうが、お願いします!!

  • プログラミング(配列と関数の引数)

    a : ABCDE a : ABCDEFGH Len : 8 a : FGHIJ a : FGH a : FGH, c : FGH 上記のように表示されるプログラムを作りたいのですが、なかなかできません。下記のようなプログラムを作ったのですがどこが間違っているのかよくわかりません。分かる方、指摘をお願いします。 #include <stdio.h> void my_strcpy(char s[], char t[]); int my_strlen(char s[]); void my_strcat(char s[], char t[]); int main(){ char a[10]; char b[10] = "ABCDE"; char c[] = "FGH"; int len; my_strcpy(a, b); printf("a : %s\n", a); my_strcat(a, c); printf("a : %s\n", a); len = my_strlen(a); printf("Len : %d\n", len); my_strcpy(a, "FGHIJ"); printf("a : %s\n", a); a[3] = '\0'; printf("a : %s\n", a); if(strcmp(a, c) == 0){ printf("a : %s, c : %s\n", a, c); } int i, s, t; my_strcpy(a, b + 2); printf("a : %s\n", a); void my_strcpy(char s[], char t[]){ for (i = 0; t[i] != '\0'; i++){ s[i] = t[i]; } s[i] = '\0'; } int my_strlen(char s[]){ int i; for (i = 0; s[i] != '\0'; i++); return i; } void my_strcat(char s[], char t[]){ int i, j; for (i = 0; s[i] != '\0'; i++); for (j = 0; t[j] != '\0'; i++, j++){ s[i] = t[j]; } s[i] = '\0'; } }

  • c言語の文字列の逆順のプログラムがわかりません

    文字列を逆順して出力するプログラミングがわかりません。 #include <stdio.h> #include <string.h> void reverse(char *moji, char *gyaku); int main(void) { char x[30]; char y[30]; puts("文字を入力してください。\n"); scanf("%s", x); reverse(x, y); printf("逆順すると%sです。\n", y); return (0); } void reverse(char *moji, char *gyaku) { int i, len; len = strlen(moji); gyaku = moji + len - 1; for(i = 0; i < len; i ++){ putchar((int)*gyaku); gyaku--; } } 理想とする実行結果は 文字を入力してください。 abcdefg 逆順するとgfedcbaです。 なんですが、 上記のソースを実行すると 文字を入力してください。 abcdefg gfedcba逆順すると(謎の漢字)です。 となります。 どこがおかしいんでしょうか? よろしくおねがいします。