質問編集履歴

1

詳細

2020/07/22 08:48

投稿

junnnnchan
junnnnchan

スコア26

test CHANGED
File without changes
test CHANGED
@@ -27,3 +27,409 @@
27
27
 
28
28
 
29
29
  結果は方法1と同じになりませんでした。
30
+
31
+ <追記>
32
+
33
+ ```
34
+
35
+ #include <stdio.h>
36
+
37
+ #include <stdlib.h>
38
+
39
+ #include <string.h>
40
+
41
+ #define swap(type, x, y) \
42
+
43
+ do \
44
+
45
+ { \
46
+
47
+ type t; \
48
+
49
+ t = x; \
50
+
51
+ x = y; \
52
+
53
+ y = t; \
54
+
55
+ } while (0)
56
+
57
+ /*--- 会員データ ---*/
58
+
59
+ typedef struct
60
+
61
+ {
62
+
63
+ int no; /* 番号 */
64
+
65
+ char name[20]; /* 氏名 */
66
+
67
+ } Member;
68
+
69
+ /*--- 会員の番号の昇順比較関数 ---*/
70
+
71
+ int AscendingMemberNoCmp(const Member *x, const Member *y)
72
+
73
+ {
74
+
75
+ return x->no < y->no ? -1 : x->no > y->no ? 1 : 0;
76
+
77
+ }
78
+
79
+ /*--- 会員の番号の降順比較関数 ---*/
80
+
81
+ int DescendingMemberNoCmp(const Member *x, const Member *y)
82
+
83
+ {
84
+
85
+ return x->no < y->no ? 1 : x->no > y->no ? -1 : 0;
86
+
87
+ }
88
+
89
+ /*--- 会員の氏名の昇順比較関数 ---*/
90
+
91
+ int AscendingMemberNameCmp(const Member *x, const Member *y)
92
+
93
+ {
94
+
95
+ return strcmp(x->name, y->name);
96
+
97
+ }
98
+
99
+ /*--- 会員の氏名の降順比較関数 ---*/
100
+
101
+ int DescendingMemberNameCmp(const Member *x, const Member *y)
102
+
103
+ {
104
+
105
+ return strcmp(y->name, x->name);
106
+
107
+ }
108
+
109
+ /*--- 会員データ(番号と氏名)の表示(改行あり)---*/
110
+
111
+ void PrintLnMember(const Member *x)
112
+
113
+ {
114
+
115
+ printf("%d %s\n", x->no, x->name);
116
+
117
+ }
118
+
119
+ /*--- 全データの表示 ---*/
120
+
121
+ void Print(const Member *data, int *m, int n)
122
+
123
+ { // Print(data, sortindex, ndata);
124
+
125
+ int i;
126
+
127
+ for (i = 0; i < n; i++)
128
+
129
+ PrintLnMember(data + i);
130
+
131
+ }
132
+
133
+
134
+
135
+ void Number_compare(Member *a, int *m, int n, int compare(const Member *y, const Member *z))
136
+
137
+ { //heapsort(data, sortindex, ndata, AscendingMemberNoCmp
138
+
139
+ int i;
140
+
141
+ int max = 9;
142
+
143
+ int *s = calloc(max + 1, sizeof(*m));
144
+
145
+ for (i = 0; i <= max; i++)
146
+
147
+ s[i] = 0;
148
+
149
+ /*度数分布表作成*/ //ok
150
+
151
+ for (i = 0; i < n; i++)
152
+
153
+ s[a[i].no]++;
154
+
155
+ /*累積分布表作成*/ //ok
156
+
157
+ for (i = 1; i <= max; i++)
158
+
159
+ {
160
+
161
+ s[i] += s[i - 1];
162
+
163
+ }
164
+
165
+ /*目的配列の作成*/
166
+
167
+ Member *b = calloc(n + 1, sizeof(Member));
168
+
169
+ for (i = n - 1; i >= 0; i--)
170
+
171
+ b[--s[(a[i].no)]] = a[i];
172
+
173
+ /*配列のコピー*/
174
+
175
+ for (i = 0; i < n; i++)
176
+
177
+ a[i] = b[i];
178
+
179
+ if (compare == DescendingMemberNoCmp)
180
+
181
+ {
182
+
183
+ for (i = 0; i < (n / 2); i++)
184
+
185
+ swap(Member, a[n - i - 1], a[i]);
186
+
187
+ }
188
+
189
+ /*解放*/
190
+
191
+ free(b);
192
+
193
+ b = NULL;
194
+
195
+ }
196
+
197
+
198
+
199
+ void Name_compare(Member *a, int *m, int n, int compare(const Member *y, const Member *z))
200
+
201
+ { //heapsort(data, sortindex, ndata, AscendingMemberNoCmp
202
+
203
+ int i;
204
+
205
+ int max = 118; //uの10進数
206
+
207
+ Member *b = calloc(max, sizeof(Member));
208
+
209
+ int *s = calloc(max + 1, sizeof(*m));
210
+
211
+ for (i = 0; i <= max; i++)
212
+
213
+ s[i] = 0;
214
+
215
+ /*度数分布表作成*/ //ok
216
+
217
+ for (i = 0; i < n; i++)
218
+
219
+ s[*(a[i].name)]++;
220
+
221
+ /*累積分布表作成*/
222
+
223
+ for (i = 1; i <= max; i++)
224
+
225
+ s[i] += s[i - 1];
226
+
227
+ for (i = n - 1; i >= 0; i--)
228
+
229
+ b[--s[*(a[i].name)]] = a[i];
230
+
231
+ /*配列のコピー*/
232
+
233
+ for (i = 0; i < n; i++)
234
+
235
+ {
236
+
237
+ a[i] = b[i];
238
+
239
+ }
240
+
241
+ /*降順の場合、昇順で並べた配列を逆順にする*/
242
+
243
+ if (compare == DescendingMemberNameCmp)
244
+
245
+ {
246
+
247
+ for (i = 0; i < (n / 2); i++)
248
+
249
+ swap(Member, a[n - i - 1], a[i]);
250
+
251
+ }
252
+
253
+ /*解放*/
254
+
255
+ free(b);
256
+
257
+ free(s);
258
+
259
+ b = NULL;
260
+
261
+ s = NULL;
262
+
263
+ }
264
+
265
+ /*--- ヒープソート ---*/
266
+
267
+ void heapsort(Member *a, int *m, int n, int compare(const Member *y, const Member *z))
268
+
269
+ { // heapsort(data, sortindex, ndata, AscendingMemberNoCmp);
270
+
271
+ //ndata == 8
272
+
273
+ if (compare == AscendingMemberNoCmp)
274
+
275
+ Number_compare(a, m, n, AscendingMemberNoCmp);
276
+
277
+ if (compare == DescendingMemberNoCmp)
278
+
279
+ Number_compare(a, m, n, DescendingMemberNoCmp);
280
+
281
+ if (compare == AscendingMemberNameCmp)
282
+
283
+ Name_compare(a, m, n, AscendingMemberNameCmp);
284
+
285
+ if (compare == DescendingMemberNameCmp)
286
+
287
+ Name_compare(a, m, n, DescendingMemberNameCmp);
288
+
289
+ }
290
+
291
+ /*--- メニュー ---*/
292
+
293
+ typedef enum
294
+
295
+ {
296
+
297
+ TERMINATE,
298
+
299
+ ASCEND_NO,
300
+
301
+ ASCEND_NAME,
302
+
303
+ DESCEND_NO,
304
+
305
+ DESCEND_NAME,
306
+
307
+ PRINT_ALL
308
+
309
+ } Menu;
310
+
311
+ /*--- メニュー選択 ---*/
312
+
313
+ Menu SelectMenu(void)
314
+
315
+ {
316
+
317
+ int i, ch;
318
+
319
+ char *mstring[] = {
320
+
321
+ "番号で昇順ソート", "名前で昇順ソート",
322
+
323
+ "番号で降順ソート", "名前で降順ソート",
324
+
325
+ "データを表示"};
326
+
327
+
328
+
329
+ do
330
+
331
+ {
332
+
333
+ for (i = TERMINATE; i < PRINT_ALL; i++)
334
+
335
+ {
336
+
337
+ printf("(%2d) %-22.22s ", i + 1, mstring[i]);
338
+
339
+ if ((i % 3) == 2)
340
+
341
+ putchar('\n');
342
+
343
+ }
344
+
345
+ printf("( 0) 終了 :");
346
+
347
+ scanf("%d", &ch);
348
+
349
+ } while (ch < TERMINATE || ch > PRINT_ALL);
350
+
351
+
352
+
353
+ return (Menu)ch;
354
+
355
+ }
356
+
357
+ /*--- メイン ---*/
358
+
359
+ int main(void)
360
+
361
+ {
362
+
363
+ Menu menu;
364
+
365
+ Member data[] = {
366
+
367
+ {1, "takahashi"}, {3, "konishi"}, {5, "ueda"}, {7, "sato"}, {9, "niimi"}, {8, "okonishi"}, {2, "motoike"}, {4, "agemi"}};
368
+
369
+ int ndata = sizeof(data) / sizeof(data[0]);
370
+
371
+ int i, *sortindex = calloc(ndata, sizeof(int));
372
+
373
+ //int sortindex[8]
374
+
375
+ for (i = 0; i < ndata; i++)
376
+
377
+ sortindex[i] = i; /* data[]の添字を管理する配列*/
378
+
379
+ do
380
+
381
+ {
382
+
383
+ switch (menu = SelectMenu())
384
+
385
+ {
386
+
387
+ case ASCEND_NO: /* 番号で昇順にソート */
388
+
389
+ heapsort(data, sortindex, ndata, AscendingMemberNoCmp);
390
+
391
+ break;
392
+
393
+ case ASCEND_NAME: /* 名前で昇順にソート */
394
+
395
+ heapsort(data, sortindex, ndata, AscendingMemberNameCmp);
396
+
397
+ break;
398
+
399
+ case DESCEND_NO: /* 番号で降順にソート */
400
+
401
+ heapsort(data, sortindex, ndata, DescendingMemberNoCmp);
402
+
403
+ break;
404
+
405
+ case DESCEND_NAME: /* 名前で降順にソート */
406
+
407
+ heapsort(data, sortindex, ndata, DescendingMemberNameCmp);
408
+
409
+ break;
410
+
411
+ case PRINT_ALL: /* 全データを表示 */
412
+
413
+ Print(data, sortindex, ndata);
414
+
415
+ break;
416
+
417
+ }
418
+
419
+ } while (menu != TERMINATE);
420
+
421
+ free(sortindex);
422
+
423
+ sortindex = NULL;
424
+
425
+ return 0;
426
+
427
+ }
428
+
429
+ ```
430
+
431
+ Name_compare関数の int *s = calloc(max + 1, sizeof(*m));をreallocで再現できないのかと思い
432
+
433
+ int *s = realloc(m,sizeof(*m)*(max + 1))
434
+
435
+ という領域確保がいいと思ったのですができませんでした。