質問編集履歴

3

2021/05/20 14:58

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,6 @@
1
1
  以下のコード(ハッシュ表)を実行するとハッシュ表にデータを挿入し、Aの長さを出力するところまではうまくいっているのですが、それ以降処理が進みません。《printf("after delete:"); 》これが出力されないのです。
2
2
 
3
- ハッシュ表削除後のlength関数をコメントすると《printf("after delete:"); 》が処理されます。l
3
+ ハッシュ表削除後のlength関数をコメントすると《printf("after delete:"); 》が処理されます。
4
4
 
5
5
  間違っている部分を教えて頂きたいです
6
6
 

2

2021/05/20 14:58

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,8 @@
1
1
  以下のコード(ハッシュ表)を実行するとハッシュ表にデータを挿入し、Aの長さを出力するところまではうまくいっているのですが、それ以降処理が進みません。《printf("after delete:"); 》これが出力されないのです。
2
2
 
3
+ ハッシュ表削除後のlength関数をコメントすると《printf("after delete:"); 》が処理されます。l
4
+
3
- 何度見直してもどの部分が間違っているのかが分かりません。間違っている部分を教えて頂きたいです
5
+ 間違っている部分を教えて頂きたいです
4
6
 
5
7
  不明な部分を指摘していただければ適宜、編集・返答します。よろしくお願いします
6
8
 

1

2021/05/20 14:57

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,441 +1,435 @@
1
1
  以下のコード(ハッシュ表)を実行するとハッシュ表にデータを挿入し、Aの長さを出力するところまではうまくいっているのですが、それ以降処理が進みません。《printf("after delete:"); 》これが出力されないのです。
2
2
 
3
+ 何度見直してもどの部分が間違っているのかが分かりません。間違っている部分を教えて頂きたいです
4
+
3
- ながら、ハッシュ表の削除後の
5
+ 不明な部分を指摘ていただければ適宜、編集・返答ます。よろしくお願いします
4
6
 
5
7
  ```
6
8
 
9
+
10
+
11
+ #include <stdio.h>
12
+
13
+ #include <stdlib.h>
14
+
15
+ #include <string.h> /* 文字列関数を扱えるようにする */
16
+
17
+ #define W 10 /* W = 文字列の最大長さ,ここでは 10 に設定 */
18
+
19
+ #define m 97 /* m = ハッシュ表のサイズ,ここでは 97 に設定 */
20
+
21
+ #define maxN 50 /* maxN = 扱う文字列の最大数,ここでは 50 に設定 */
22
+
23
+
24
+
25
+ struct cell
26
+
27
+ {
28
+
29
+ char key[W+1]; int next; /* 構造体 cell の定義 */
30
+
31
+ };
32
+
33
+
34
+
35
+ int allocate_object(struct cell *L, int *f); /* 関数 allocate_object の宣言 */
36
+
37
+ int chained_hash_search(int *A, struct cell *L, char *a); /* 関数 chained_hash_searchの宣言 */
38
+
39
+ int hash_val(char *a);
40
+
41
+ void chained_hash_insert(int *A, struct cell *L, int x);
42
+
43
+ int length(struct cell *L, int a);
44
+
45
+ void chained_hash_delete(int *A, struct cell *L, int x);
46
+
47
+ void free_object(struct cell *L, int *f, int x);
48
+
49
+ int Serch(int *A, struct cell *L, int x);
50
+
51
+
52
+
53
+ int main(void)
54
+
55
+ {
56
+
57
+ struct cell List[maxN]; /* リストは cell の配列,数値数は n まで */
58
+
59
+ int A[m]; /* ハッシュ表を表す配列 */
60
+
61
+ int N; /* 数値の数は N */
62
+
63
+ int freeL; /* 空きアドレスのリストの先頭*/
64
+
65
+ int i, h, y, x, b;
66
+
67
+ char word[W+1]; /* ファイルから読み込んだ文字列を格納する変数 */
68
+
69
+ char fname[128]; /* 読み込むファイルの名前 */
70
+
71
+ FILE *fp; /* 入力ファイル */
72
+
73
+ for (i=0; i<maxN-1; i++){ /* allocate_object, free_object のための初期化 */
74
+
75
+ List[i].next = i+1;
76
+
77
+ }
78
+
79
+ List[maxN-1].next = -1;
80
+
81
+ freeL = 0; /* 空きリストの初期化 */
82
+
83
+ for (h=0; h<m; h++){
84
+
85
+ A[h] = -1;
86
+
87
+ } /* ハッシュ表の初期化 */
88
+
89
+
90
+
91
+ printf("input filename: "); /* ファイル名の入力を要求 */
92
+
93
+ fgets(fname, sizeof(fname), stdin); /* ファイル名取得 */
94
+
95
+ fname[strlen(fname)-1] = '\0';
96
+
97
+ fflush(stdin);
98
+
99
+ fp = fopen(fname, "r"); /* ファイルを読み込みモードで開く */
100
+
101
+ fscanf(fp, "%d", &N); /* N をファイルから読み込む */
102
+
103
+ if (N > maxN){
104
+
105
+ printf("N is too large, setting N = %d\n", maxN);
106
+
107
+ N = maxN;
108
+
109
+ }
110
+
111
+ for (i=0; i<N; i++){
112
+
113
+ fscanf(fp, "%s", word); /* 文字列をファイルから読み込み,wordに格納 */
114
+
115
+ y = chained_hash_search(A, List, word); /* ハッシュ表の中で文字列 word を探索 */
116
+
117
+ if (y == -1){
118
+
119
+ x = allocate_object(List, &freeL);
120
+
121
+ strcpy(List[x].key, word);
122
+
123
+ chained_hash_insert(A, List, x);
124
+
125
+ }
126
+
127
+
128
+
129
+ }
130
+
131
+ fclose(fp); /* 開いたファイルを一旦閉じる */
132
+
133
+
134
+
135
+ for (h=0; h<m; h++){
136
+
137
+ b = length(List, A[h]);
138
+
139
+ if(b != 0)
140
+
141
+ {
142
+
143
+ printf("A[%d]の長さは%d\n", h, b);
144
+
145
+ }
146
+
147
+ /* ハッシュ表のアドレス h が指す*/
148
+
149
+ /* リスト A[h] の長さを出力 */
150
+
151
+ }
152
+
153
+ fp = fopen(fname, "r"); /* ファイルを再度読み込みモードで開く */
154
+
155
+ fscanf(fp, "%d", &N); /* N をファイルから読み込む */
156
+
157
+ if (N > maxN){N = maxN;}
158
+
159
+ for (i=0; i<N; i++){
160
+
161
+ fscanf(fp, "%s", word); /* 文字列をファイルから読み込み,wordに格納 */
162
+
163
+ x = chained_hash_search(A, List, word);
164
+
165
+ if(x != -1)
166
+
167
+ {
168
+
169
+ chained_hash_delete(A, List, x);/* データを削除する部分 */
170
+
171
+ free_object(List, &freeL, x);
172
+
173
+ }
174
+
175
+ }
176
+
177
+ fclose(fp); /* 開いたファイルを閉じる */
178
+
179
+
180
+
181
+ printf("after delete:");
182
+
183
+ for (h=0; h<m; h++){
184
+
7
185
  b = length(List, A[h]);
8
186
 
187
+ if(b != 0)
188
+
189
+ {
190
+
191
+ printf("A[%d]の長さは%d\n", h, h);
192
+
193
+ }
194
+
195
+ /* ハッシュ表のアドレス h が指す*/
196
+
197
+ /* リスト A[h] の長さを出力 */
198
+
199
+ }
200
+
201
+ printf("\n");
202
+
203
+ return 0;
204
+
205
+ }
206
+
207
+
208
+
209
+ int hash_val(char *a) /* 文字列はポインタ渡し */
210
+
211
+ {
212
+
213
+ int h, i;
214
+
215
+ h = 0; i = 0;
216
+
217
+ while (a[i] != 0 && i < W) /* 文字の整数コードの和を計算 */
218
+
219
+ {
220
+
221
+ h = h + (int)a[i];
222
+
223
+ i = i + 1;
224
+
225
+ }
226
+
227
+ h = h % m; /* m で割った余りを取る */
228
+
229
+ return h;
230
+
231
+ }
232
+
233
+
234
+
235
+ int chained_hash_search(int *A, struct cell *L, char *a)
236
+
237
+ {
238
+
239
+ int x,h;
240
+
241
+ h = hash_val(a);
242
+
243
+ x = A[h];
244
+
245
+
246
+
247
+ while(x != -1 && strcmp(L[x].key, a) != 0)
248
+
249
+ {
250
+
251
+ x = L[x].next;
252
+
253
+ }
254
+
255
+
256
+
257
+ return x;
258
+
259
+ }
260
+
261
+
262
+
263
+ int allocate_object(struct cell *L, int *f)
264
+
265
+ { /* リスト配列と空きアドレスリスト先頭はポインタ渡し */
266
+
267
+ int x;
268
+
269
+ if (*f == -1){printf("error: out of space\n"); x = -1;}
270
+
271
+ /* 空きアドレスがなければエラーメッセージを表示*/
272
+
273
+ else {
274
+
275
+ x = *f;
276
+
277
+ *f = L[*f].next;
278
+
279
+ }
280
+
281
+ return x;
282
+
283
+ }
284
+
285
+
286
+
287
+ void free_object(struct cell *L, int *f, int x)
288
+
289
+ {
290
+
291
+ L[x].next = *f;
292
+
293
+ *f = x;
294
+
295
+ }
296
+
297
+
298
+
299
+ void chained_hash_insert(int *A, struct cell *L, int x)
300
+
301
+ {
302
+
303
+ int h;
304
+
305
+ h = hash_val(L[x].key);
306
+
307
+ L[x].next = A[h];
308
+
309
+ A[h] = x;
310
+
311
+ }
312
+
313
+
314
+
315
+ int length(struct cell *L, int a)
316
+
317
+ {
318
+
319
+ int i = 0;
320
+
321
+
322
+
323
+ if(a != -1)
324
+
325
+ {
326
+
327
+ while(L[a].next != -1)
328
+
329
+ {
330
+
331
+ i = i + 1;
332
+
333
+ a = L[a].next;
334
+
335
+ }
336
+
337
+ i = i + 1;
338
+
339
+ }
340
+
341
+
342
+
343
+ return i;
344
+
345
+ }
346
+
347
+
348
+
349
+ void chained_hash_delete(int *A, struct cell *L, int x)/*セルをリストから削除*/
350
+
351
+ {
352
+
353
+ int h,z;
354
+
355
+
356
+
357
+ h = hash_val(L[x].key);
358
+
359
+
360
+
361
+ z = Serch(A, L, x);
362
+
363
+
364
+
365
+ if(z != -1)
366
+
367
+ {
368
+
369
+ L[z].next = L[x].next;
370
+
371
+ }
372
+
373
+
374
+
375
+ else
376
+
377
+ {
378
+
379
+ A[h] = L[x].next;
380
+
381
+ }
382
+
383
+ }
384
+
385
+
386
+
387
+ int Serch(int *A, struct cell *L, int x)
388
+
389
+ {
390
+
391
+ int h,y=0;
392
+
393
+
394
+
395
+ for(h=0; h<m; h++)
396
+
397
+ {
398
+
399
+ if(A[h] == x)
400
+
401
+ {
402
+
403
+ y = -1;
404
+
405
+ }
406
+
407
+ }
408
+
409
+ if(y != -1){
410
+
411
+ for(h=0; h<m; h++)
412
+
413
+ {
414
+
415
+ if(L[h].next == x)
416
+
417
+ {
418
+
419
+ y = h;
420
+
421
+ }
422
+
423
+ }
424
+
425
+
426
+
427
+ }
428
+
429
+ return y;
430
+
431
+ }
432
+
433
+
434
+
9
435
  ```
10
-
11
- をコメントアウトすると《printf("after delete:"); 》が出力されます。原因はlength関数であるとは考えているのですが、どこが間違っているかわからないため教えていただきたいです。説明が下手で申し訳ないです。不明な部分を指摘していただければ適宜、編集・返答します。よろしくお願いします
12
-
13
- ```
14
-
15
-
16
-
17
- #include <stdio.h>
18
-
19
- #include <stdlib.h>
20
-
21
- #include <string.h> /* 文字列関数を扱えるようにする */
22
-
23
- #define W 10 /* W = 文字列の最大長さ,ここでは 10 に設定 */
24
-
25
- #define m 97 /* m = ハッシュ表のサイズ,ここでは 97 に設定 */
26
-
27
- #define maxN 50 /* maxN = 扱う文字列の最大数,ここでは 50 に設定 */
28
-
29
-
30
-
31
- struct cell
32
-
33
- {
34
-
35
- char key[W+1]; int next; /* 構造体 cell の定義 */
36
-
37
- };
38
-
39
-
40
-
41
- int allocate_object(struct cell *L, int *f); /* 関数 allocate_object の宣言 */
42
-
43
- int chained_hash_search(int *A, struct cell *L, char *a); /* 関数 chained_hash_searchの宣言 */
44
-
45
- int hash_val(char *a);
46
-
47
- void chained_hash_insert(int *A, struct cell *L, int x);
48
-
49
- int length(struct cell *L, int a);
50
-
51
- void chained_hash_delete(int *A, struct cell *L, int x);
52
-
53
- void free_object(struct cell *L, int *f, int x);
54
-
55
- int Serch(int *A, struct cell *L, int x);
56
-
57
-
58
-
59
- int main(void)
60
-
61
- {
62
-
63
- struct cell List[maxN]; /* リストは cell の配列,数値数は n まで */
64
-
65
- int A[m]; /* ハッシュ表を表す配列 */
66
-
67
- int N; /* 数値の数は N */
68
-
69
- int freeL; /* 空きアドレスのリストの先頭*/
70
-
71
- int i, h, y, x, b;
72
-
73
- char word[W+1]; /* ファイルから読み込んだ文字列を格納する変数 */
74
-
75
- char fname[128]; /* 読み込むファイルの名前 */
76
-
77
- FILE *fp; /* 入力ファイル */
78
-
79
- for (i=0; i<maxN-1; i++){ /* allocate_object, free_object のための初期化 */
80
-
81
- List[i].next = i+1;
82
-
83
- }
84
-
85
- List[maxN-1].next = -1;
86
-
87
- freeL = 0; /* 空きリストの初期化 */
88
-
89
- for (h=0; h<m; h++){
90
-
91
- A[h] = -1;
92
-
93
- } /* ハッシュ表の初期化 */
94
-
95
-
96
-
97
- printf("input filename: "); /* ファイル名の入力を要求 */
98
-
99
- fgets(fname, sizeof(fname), stdin); /* ファイル名取得 */
100
-
101
- fname[strlen(fname)-1] = '\0';
102
-
103
- fflush(stdin);
104
-
105
- fp = fopen(fname, "r"); /* ファイルを読み込みモードで開く */
106
-
107
- fscanf(fp, "%d", &N); /* N をファイルから読み込む */
108
-
109
- if (N > maxN){
110
-
111
- printf("N is too large, setting N = %d\n", maxN);
112
-
113
- N = maxN;
114
-
115
- }
116
-
117
- for (i=0; i<N; i++){
118
-
119
- fscanf(fp, "%s", word); /* 文字列をファイルから読み込み,wordに格納 */
120
-
121
- y = chained_hash_search(A, List, word); /* ハッシュ表の中で文字列 word を探索 */
122
-
123
- if (y == -1){
124
-
125
- x = allocate_object(List, &freeL);
126
-
127
- strcpy(List[x].key, word);
128
-
129
- chained_hash_insert(A, List, x);
130
-
131
- }
132
-
133
-
134
-
135
- }
136
-
137
- fclose(fp); /* 開いたファイルを一旦閉じる */
138
-
139
-
140
-
141
- for (h=0; h<m; h++){
142
-
143
- b = length(List, A[h]);
144
-
145
- if(b != 0)
146
-
147
- {
148
-
149
- printf("A[%d]の長さは%d\n", h, b);
150
-
151
- }
152
-
153
- /* ハッシュ表のアドレス h が指す*/
154
-
155
- /* リスト A[h] の長さを出力 */
156
-
157
- }
158
-
159
- fp = fopen(fname, "r"); /* ファイルを再度読み込みモードで開く */
160
-
161
- fscanf(fp, "%d", &N); /* N をファイルから読み込む */
162
-
163
- if (N > maxN){N = maxN;}
164
-
165
- for (i=0; i<N; i++){
166
-
167
- fscanf(fp, "%s", word); /* 文字列をファイルから読み込み,wordに格納 */
168
-
169
- x = chained_hash_search(A, List, word);
170
-
171
- if(x != -1)
172
-
173
- {
174
-
175
- chained_hash_delete(A, List, x);/* データを削除する部分 */
176
-
177
- free_object(List, &freeL, x);
178
-
179
- }
180
-
181
- }
182
-
183
- fclose(fp); /* 開いたファイルを閉じる */
184
-
185
-
186
-
187
- printf("after delete:");
188
-
189
- for (h=0; h<m; h++){
190
-
191
- b = length(List, A[h]);
192
-
193
- if(b != 0)
194
-
195
- {
196
-
197
- printf("A[%d]の長さは%d\n", h, h);
198
-
199
- }
200
-
201
- /* ハッシュ表のアドレス h が指す*/
202
-
203
- /* リスト A[h] の長さを出力 */
204
-
205
- }
206
-
207
- printf("\n");
208
-
209
- return 0;
210
-
211
- }
212
-
213
-
214
-
215
- int hash_val(char *a) /* 文字列はポインタ渡し */
216
-
217
- {
218
-
219
- int h, i;
220
-
221
- h = 0; i = 0;
222
-
223
- while (a[i] != 0 && i < W) /* 文字の整数コードの和を計算 */
224
-
225
- {
226
-
227
- h = h + (int)a[i];
228
-
229
- i = i + 1;
230
-
231
- }
232
-
233
- h = h % m; /* m で割った余りを取る */
234
-
235
- return h;
236
-
237
- }
238
-
239
-
240
-
241
- int chained_hash_search(int *A, struct cell *L, char *a)
242
-
243
- {
244
-
245
- int x,h;
246
-
247
- h = hash_val(a);
248
-
249
- x = A[h];
250
-
251
-
252
-
253
- while(x != -1 && strcmp(L[x].key, a) != 0)
254
-
255
- {
256
-
257
- x = L[x].next;
258
-
259
- }
260
-
261
-
262
-
263
- return x;
264
-
265
- }
266
-
267
-
268
-
269
- int allocate_object(struct cell *L, int *f)
270
-
271
- { /* リスト配列と空きアドレスリスト先頭はポインタ渡し */
272
-
273
- int x;
274
-
275
- if (*f == -1){printf("error: out of space\n"); x = -1;}
276
-
277
- /* 空きアドレスがなければエラーメッセージを表示*/
278
-
279
- else {
280
-
281
- x = *f;
282
-
283
- *f = L[*f].next;
284
-
285
- }
286
-
287
- return x;
288
-
289
- }
290
-
291
-
292
-
293
- void free_object(struct cell *L, int *f, int x)
294
-
295
- {
296
-
297
- L[x].next = *f;
298
-
299
- *f = x;
300
-
301
- }
302
-
303
-
304
-
305
- void chained_hash_insert(int *A, struct cell *L, int x)
306
-
307
- {
308
-
309
- int h;
310
-
311
- h = hash_val(L[x].key);
312
-
313
- L[x].next = A[h];
314
-
315
- A[h] = x;
316
-
317
- }
318
-
319
-
320
-
321
- int length(struct cell *L, int a)
322
-
323
- {
324
-
325
- int i = 0;
326
-
327
-
328
-
329
- if(a != -1)
330
-
331
- {
332
-
333
- while(L[a].next != -1)
334
-
335
- {
336
-
337
- i = i + 1;
338
-
339
- a = L[a].next;
340
-
341
- }
342
-
343
- i = i + 1;
344
-
345
- }
346
-
347
-
348
-
349
- return i;
350
-
351
- }
352
-
353
-
354
-
355
- void chained_hash_delete(int *A, struct cell *L, int x)/*セルをリストから削除*/
356
-
357
- {
358
-
359
- int h,z;
360
-
361
-
362
-
363
- h = hash_val(L[x].key);
364
-
365
-
366
-
367
- z = Serch(A, L, x);
368
-
369
-
370
-
371
- if(z != -1)
372
-
373
- {
374
-
375
- L[z].next = L[x].next;
376
-
377
- }
378
-
379
-
380
-
381
- else
382
-
383
- {
384
-
385
- A[h] = L[x].next;
386
-
387
- }
388
-
389
- }
390
-
391
-
392
-
393
- int Serch(int *A, struct cell *L, int x)
394
-
395
- {
396
-
397
- int h,y=0;
398
-
399
-
400
-
401
- for(h=0; h<m; h++)
402
-
403
- {
404
-
405
- if(A[h] == x)
406
-
407
- {
408
-
409
- y = -1;
410
-
411
- }
412
-
413
- }
414
-
415
- if(y != -1){
416
-
417
- for(h=0; h<m; h++)
418
-
419
- {
420
-
421
- if(L[h].next == x)
422
-
423
- {
424
-
425
- y = h;
426
-
427
- }
428
-
429
- }
430
-
431
-
432
-
433
- }
434
-
435
- return y;
436
-
437
- }
438
-
439
-
440
-
441
- ```