質問編集履歴

1

ソースコード修正しました

2017/01/31 00:49

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -8,79 +8,349 @@
8
8
 
9
9
  データ構造を維持してなるべく高速なソートを行いたいのですが実装ができません.
10
10
 
11
- 以下のマージソートで実装してみましたがSegmentation faultが出力されました.
11
+ ~~以下のマージソートで実装してみましたがSegmentation faultが出力されました.~~
12
+
13
+ 以下のソースコードで実行してもソートされません.
12
14
 
13
15
  ご教授よろしくお願いします.
14
16
 
15
17
 
16
18
 
19
+ **ソースコード修正しました(getwordは修正できていません).**
20
+
21
+ ハッシュテーブルの各セルの末尾を連結して1つのリストとするのが有効だと考えました.
22
+
23
+
24
+
17
25
  ```C
18
26
 
27
+ #include <stddef.h>
28
+
29
+ #include <stdio.h>
30
+
31
+ #include <stdlib.h>
32
+
33
+ #include <ctype.h>
34
+
35
+ #include <string.h>
36
+
37
+
38
+
39
+ #define WORDLEN 50
40
+
41
+ #define SIZE 32
42
+
43
+
44
+
45
+ struct wd {
46
+
47
+ struct wd *next;
48
+
49
+ char *str;
50
+
51
+ int count;
52
+
53
+ };
54
+
55
+ typedef struct wd WORD;
56
+
57
+
58
+
59
+ WORD *word[SIZE];
60
+
61
+
62
+
63
+ void init_word();
64
+
65
+ WORD *add_word(char *);
66
+
67
+ char *getword(char *, int);
68
+
69
+ int hash(char *w);
70
+
19
- WORD *merge_list(WORD *xs, WORD *ys)
71
+ WORD *merge_list(WORD *w1, WORD *w2);
72
+
73
+ WORD *merge_sort(WORD *w);
74
+
75
+
76
+
77
+ int main()
20
78
 
21
79
  {
22
80
 
81
+ char w[WORDLEN];
82
+
23
- WORD head;
83
+ WORD *p;
84
+
24
-
85
+ int i;
86
+
87
+
88
+
25
- WORD *wd = &head;
89
+ init_word();
26
-
90
+
27
- while (xs != NULL && ys != NULL) {
91
+ while (getword(w, WORDLEN) != NULL) {
28
-
29
- if (xs->count <= ys->count) {
92
+
30
-
31
- wd->next = xs;
32
-
33
- wd = xs;
34
-
35
- xs = xs->next;
93
+ p = add_word(w);
36
-
37
- } else {
94
+
38
-
39
- wd->next = ys;
95
+ if (p == NULL) {
96
+
40
-
97
+ fprintf(stderr, "Too many words\n");
98
+
41
- wd = ys;
99
+ exit(1);
42
-
43
- ys = ys->next;
100
+
44
-
45
- }
101
+ }
102
+
46
-
103
+ p->count++;
104
+
47
- }
105
+ }
48
-
49
- if (xs != NULL)
106
+
50
-
107
+
108
+
51
- wd->next = xs;
109
+ for (i = 0; i < SIZE; i++) {
52
-
53
- else
110
+
54
-
55
- wd->next = ys;
111
+ for (p = word[i]; p != NULL; p = p->next) {
56
-
112
+
57
- return head.next;
113
+ printf("%d %s\n", p->count, p->str);
58
-
114
+
59
- }
115
+ }
116
+
60
-
117
+ }
118
+
61
-
119
+ return 0;
120
+
62
-
121
+ }
122
+
123
+
124
+
125
+
126
+
63
- WORD *merge_sort(WORD *wd, int n)
127
+ void init_word()
64
128
 
65
129
  {
66
130
 
67
- if (n == 1) {
68
-
69
- wd->next = NULL;
70
-
71
- return wd;
72
-
73
- } else {
74
-
75
- int m = n / 2;
76
-
77
- WORD *xs = wd;
78
-
79
- for (int i = 0; i < m; i++) xs = xs->next;
80
-
81
- return merge_list(merge_sort(wd, m), merge_sort(xs, n - m));
82
-
83
- }
131
+ int i;
132
+
133
+
134
+
135
+ for (i = 0; i < SIZE; i++)
136
+
137
+ word[i] = NULL;
138
+
139
+ }
140
+
141
+
142
+
143
+
144
+
145
+ WORD *add_word(char *w)
146
+
147
+ {
148
+
149
+ char *s;
150
+
151
+ WORD *p;
152
+
153
+ int i;
154
+
155
+
156
+
157
+ i = hash(w);
158
+
159
+ for (p = word[i]; p != NULL; p = p->next) {
160
+
161
+ if (strcmp(w, p->str) == 0)
162
+
163
+ return p;
164
+
165
+ }
166
+
167
+ s = (char *)malloc(strlen(w) + 1);
168
+
169
+ if (s == NULL)
170
+
171
+ return NULL;
172
+
173
+ strcpy(s, w);
174
+
175
+ p = (WORD *)malloc(sizeof(WORD));
176
+
177
+ if (p == NULL)
178
+
179
+ return NULL;
180
+
181
+ p->str = s;
182
+
183
+ p->count = 0;
184
+
185
+ if (word[i] == NULL && i != SIZE - 1)
186
+
187
+ p->next = word[i + 1];
188
+
189
+ p->next = word[i];
190
+
191
+ word[i] = p;
192
+
193
+ return p;
194
+
195
+ }
196
+
197
+
198
+
199
+ char *getword(char *w, int n)
200
+
201
+ {
202
+
203
+ int i = 0;
204
+
205
+ int c;
206
+
207
+
208
+
209
+ if (n <= 0 || feof(stdin))
210
+
211
+ return NULL;
212
+
213
+ c = getchar();
214
+
215
+ while (c != EOF && ! isalpha(c)) {
216
+
217
+ c = getchar();
218
+
219
+ }
220
+
221
+ if (c == EOF)
222
+
223
+ return NULL;
224
+
225
+ while (isalpha(c)) {
226
+
227
+ if (i < n - 1) {
228
+
229
+ w[i] = toupper(c);
230
+
231
+ i++;
232
+
233
+ }
234
+
235
+ c = getchar();
236
+
237
+ }
238
+
239
+ w[i] = '\0';
240
+
241
+ return w;
242
+
243
+ }
244
+
245
+
246
+
247
+ int hash(char *w)
248
+
249
+ {
250
+
251
+ int i;
252
+
253
+ unsigned int h = 0;
254
+
255
+
256
+
257
+ for (i = 0; w[i] != '\0'; i++)
258
+
259
+ h = 65599 * h + w[i];
260
+
261
+ return h % SIZE;
262
+
263
+ }
264
+
265
+
266
+
267
+ WORD *merge_list (WORD *w1,WORD *w2) {
268
+
269
+ WORD out, *w;
270
+
271
+ w = &out;
272
+
273
+
274
+
275
+ while ( w1 != NULL && w2 != NULL ) {
276
+
277
+ if ( w1->str <= w2->str ) {
278
+
279
+ w->next = w1;
280
+
281
+ w = w1;
282
+
283
+ w1 = w1->next;
284
+
285
+ }
286
+
287
+ else {
288
+
289
+ w->next = w2;
290
+
291
+ w = w2;
292
+
293
+ w2 = w2->next;
294
+
295
+ }
296
+
297
+ }
298
+
299
+
300
+
301
+ if ( w1 == NULL ) {
302
+
303
+ w->next = w2;
304
+
305
+ }
306
+
307
+ else {
308
+
309
+ w->next = w1;
310
+
311
+ }
312
+
313
+
314
+
315
+ return out.next;
316
+
317
+ }
318
+
319
+
320
+
321
+ WORD *merge_sort (WORD *w) {
322
+
323
+ WORD *a, *b, *y;
324
+
325
+
326
+
327
+ if ( w == NULL || w->next == NULL ) return w;
328
+
329
+
330
+
331
+ a = w;
332
+
333
+ b = w->next->next;
334
+
335
+
336
+
337
+ while ( b!=NULL && b->next!=NULL ) {
338
+
339
+ a = a->next;
340
+
341
+ b = b->next->next;
342
+
343
+ }
344
+
345
+
346
+
347
+ y = a->next;
348
+
349
+ a->next = NULL;
350
+
351
+
352
+
353
+ return merge_list( merge_sort(w),merge_sort(y) );
84
354
 
85
355
  }
86
356
 
@@ -92,312 +362,52 @@
92
362
 
93
363
 
94
364
 
95
- ###該当のソースコード
365
+ ####実行結果
96
-
97
- 以下はソートせずに出現回数を出力します.
98
-
99
- ```C
100
-
101
- #include <stddef.h>
102
-
103
- #include <stdio.h>
104
-
105
- #include <stdlib.h>
106
-
107
- #include <ctype.h>
108
-
109
- #include <string.h>
110
-
111
-
112
-
113
- #define WORDLEN 50
114
-
115
- #define SIZE 32
116
-
117
-
118
-
119
- struct wd {
120
-
121
- struct wd *next;
122
-
123
- char *str;
124
-
125
- int count;
126
-
127
- };
128
-
129
- typedef struct wd WORD;
130
-
131
-
132
-
133
- WORD *word[SIZE];
134
-
135
-
136
-
137
- void init_word();
138
-
139
- WORD *add_word(char *);
140
-
141
- char *getword(char *, int);
142
-
143
- int hash(char *w);
144
-
145
-
146
-
147
-
148
-
149
- int main()
150
-
151
- {
152
-
153
- char w[WORDLEN];
154
-
155
- WORD *p;
156
-
157
- int i;
158
-
159
-
160
-
161
- init_word();
162
-
163
- while (getword(w, WORDLEN) != NULL) {
164
-
165
- p = add_word(w);
166
-
167
- if (p == NULL) {
168
-
169
- fprintf(stderr, "Too many words\n");
170
-
171
- exit(1);
172
-
173
- }
174
-
175
- p->count++;
176
-
177
- }
178
-
179
- for (i = 0; i < SIZE; i++) {
180
-
181
- for (p = word[i]; p != NULL; p = p->next) {
182
-
183
- printf("%d %s\n", p->count, p->str);
184
-
185
- }
186
-
187
- }
188
-
189
- return 0;
190
-
191
- }
192
-
193
-
194
-
195
-
196
-
197
- void init_word()
198
-
199
- {
200
-
201
- int i;
202
-
203
-
204
-
205
- for (i = 0; i < SIZE; i++)
206
-
207
- word[i] = NULL;
208
-
209
- }
210
-
211
-
212
-
213
-
214
-
215
- WORD *add_word(char *w)
216
-
217
- {
218
-
219
- char *s;
220
-
221
- WORD *p;
222
-
223
- int i;
224
-
225
-
226
-
227
- i = hash(w);
228
-
229
- for (p = word[i]; p != NULL; p = p->next) {
230
-
231
- if (strcmp(w, p->str) == 0)
232
-
233
- return p;
234
-
235
- }
236
-
237
- s = (char *)malloc(strlen(w) + 1);
238
-
239
- if (s == NULL)
240
-
241
- return NULL;
242
-
243
- strcpy(s, w);
244
-
245
- p = (WORD *)malloc(sizeof(WORD));
246
-
247
- if (p == NULL)
248
-
249
- return NULL;
250
-
251
- p->str = s;
252
-
253
- p->count = 0;
254
-
255
- p->next = word[i];
256
-
257
- word[i] = p;
258
-
259
- return p;
260
-
261
- }
262
-
263
-
264
-
265
-
266
-
267
- // 単語を大文字に変換する
268
-
269
- // n: 変換する単語の最大文字数
270
-
271
- // 戻り値: 格納する単語の先頭ポインタ
272
-
273
- char *getword(char *w, int n)
274
-
275
- {
276
-
277
- int c;
278
-
279
- int i = 0;
280
-
281
-
282
-
283
- if (n <= 0 || feof(stdin))
284
-
285
- return NULL;
286
-
287
- c = getchar();
288
-
289
- // cがファイルの末尾でなくアルファベットでない限り標準入力から文字をcに格納する
290
-
291
- while (c != EOF && ! isalpha(c)) {
292
-
293
- c = getchar();
294
-
295
- }
296
-
297
- // ファイルの末尾ならばNULLを返す
298
-
299
- if (c == EOF)
300
-
301
- return NULL;
302
-
303
- // cがアルファベットである限り大文字に変換しwに格納
304
-
305
- while (isalpha(c)) {
306
-
307
- if (i < n - 1)
308
-
309
- // cを大文字に変換したものをw[i]に格納後, インデックスiをインクリメントする
310
-
311
- w[i++] = toupper(c);
312
-
313
- // 標準入力からcに文字を格納する
314
-
315
- c = getchar();
316
-
317
- }
318
-
319
- // 末尾にヌル文字を追加
320
-
321
- if (i < n)
322
-
323
- w[i++] = '\0';
324
-
325
- return w;
326
-
327
- }
328
-
329
-
330
-
331
- int hash(char *w)
332
-
333
- {
334
-
335
- int i;
336
-
337
- unsigned int h = 0;
338
-
339
-
340
-
341
- for (i = 0; w[i] != '\0'; i++)
342
-
343
- h = 65599 * h + w[i];
344
-
345
- return h % SIZE;
346
-
347
- }
348
-
349
-
350
366
 
351
367
  ```
352
368
 
353
-
369
+ 31 INTO
370
+
354
-
371
+ 2 MELT
372
+
355
- ####実行結果
373
+ 1 ACCORD
374
+
375
+ 9 BREATH
376
+
377
+ 7 DIE
378
+
379
+ 1 PERSONAL
380
+
381
+ 11 BUSINESS
382
+
383
+ 16 BROTHER
384
+
385
+ 6 II
386
+
387
+ 5 GAINST
388
+
389
+ 1 PROBATION
390
+
391
+ 1 CROSS
392
+
393
+ 78 LL
394
+
395
+ 1 COUNTRYMEN
396
+
397
+ 27 HEAD
398
+
399
+ 1 SKIRTS
400
+
401
+ 1 AVOUCH
402
+
403
+ 1 FORTIFIED
404
+
405
+ 15 THEREFORE
406
+
407
+ 33 AGAIN
408
+
409
+ 3 POST
410
+
411
+
356
412
 
357
413
  ```
358
-
359
- 31 INTO
360
-
361
- 2 MELT
362
-
363
- 1 ACCORD
364
-
365
- 9 BREATH
366
-
367
- 7 DIE
368
-
369
- 1 PERSONAL
370
-
371
- 11 BUSINESS
372
-
373
- 16 BROTHER
374
-
375
- 6 II
376
-
377
- 5 GAINST
378
-
379
- 1 PROBATION
380
-
381
- 1 CROSS
382
-
383
- 78 LL
384
-
385
- 1 COUNTRYMEN
386
-
387
- 27 HEAD
388
-
389
- 1 SKIRTS
390
-
391
- 1 AVOUCH
392
-
393
- 1 FORTIFIED
394
-
395
- 15 THEREFORE
396
-
397
- 33 AGAIN
398
-
399
- 3 POST
400
-
401
-
402
-
403
- ```