回答編集履歴

3

ソートを止め, put/get で検索

2020/04/27 09:33

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -12,12 +12,10 @@
12
12
 
13
13
  #修正
14
14
 
15
- リストを使うようにし, 2次元動作するようにしました.
15
+ リストを使うようにし, 2次元的に動作するようにしました.
16
16
 
17
17
  データが無い所を 0 表示するようにしました.
18
18
 
19
- ソート部分がテキトウかもしれません.
20
-
21
19
  ```c
22
20
 
23
21
  #include <stdio.h>
@@ -76,7 +74,7 @@
76
74
 
77
75
 
78
76
 
79
- //リスト初期化
77
+ //初期化
80
78
 
81
79
  void slist_init(SLIST *slist) {
82
80
 
@@ -88,14 +86,26 @@
88
86
 
89
87
 
90
88
 
91
- //リストに追加
89
+ //書き換えor追加
92
-
90
+
93
- void slist_append(SLIST *slist, int x, int y, double v) {
91
+ void slist_put(SLIST *slist, int x, int y, double v) {
94
92
 
95
93
  SLOBJ *p;
96
94
 
97
95
 
98
96
 
97
+ for(p=slist->next; p!=NULL; p=p->next) {
98
+
99
+ if(p->x == x && p->y == y) {
100
+
101
+ p->v = v;
102
+
103
+ return;
104
+
105
+ }
106
+
107
+ }
108
+
99
109
  p = slobj_new(x, y, v);
100
110
 
101
111
  slist->last->next = p;
@@ -106,234 +116,160 @@
106
116
 
107
117
 
108
118
 
109
- //リストをカウント
119
+ //取り出し
110
-
120
+
111
- int slist_count(SLIST *slist) {
121
+ double slist_get(SLIST *slist, int x, int y) {
112
-
113
- int count;
114
122
 
115
123
  SLOBJ *p;
116
124
 
117
125
 
118
126
 
119
- count = 0;
120
-
121
- for(p=slist->next; p!=NULL; p=p->next) count++;
127
+ for(p=slist->next; p!=NULL; p=p->next) {
122
-
128
+
123
- return count;
129
+ if(p->x == x && p->y == y) return p->v;
124
-
130
+
125
- }
131
+ }
132
+
126
-
133
+ return 0.0;
134
+
127
-
135
+ }
128
-
136
+
137
+
138
+
129
- //リストをソート
139
+ //解放
130
-
140
+
131
- void slist_sort(SLIST *slist) {
141
+ void slist_clear(SLIST *slist) {
132
-
142
+
133
- SLOBJ *o, *p, *q, *t;
143
+ SLOBJ *p, *q;
134
-
135
- int count, changed;
144
+
136
-
137
-
138
-
139
- count = slist_count(slist);
145
+ for(p=slist->next; p!=NULL; p=q) {
140
-
141
- if(count <= 1) return;
142
-
143
-
144
-
145
- t = NULL;
146
-
147
- do { //バブル
148
-
149
- changed = 0; //フラグクリア
150
-
151
- o = (SLOBJ *)slist;
152
-
153
- p = o->next;
154
146
 
155
147
  q = p->next;
156
148
 
157
- while(q != t) {
149
+ free(p);
158
-
159
- if(p->y > q->y || (p->y == q->y && p->x > q->x)) { //p>q
150
+
160
-
161
- p->next = q->next; q->next = p; o->next = q; //入れ替え
162
-
163
- changed = 1; //フラグセット
164
-
165
- }
151
+ }
152
+
166
-
153
+ slist_init(slist);
154
+
155
+ }
156
+
157
+
158
+
159
+ //疎行列の構造体
160
+
161
+ typedef struct {
162
+
163
+ int n, m;
164
+
165
+ SLIST a;
166
+
167
+ } SMATRIX;
168
+
169
+
170
+
171
+ //新しい疎行列を作成
172
+
173
+ SMATRIX *smatrix_new(int n, int m) {
174
+
175
+ SMATRIX *s;
176
+
177
+
178
+
179
+ s = (SMATRIX *)malloc(sizeof(SMATRIX));
180
+
181
+ s->n = n;
182
+
183
+ s->m = m;
184
+
185
+ slist_init(&s->a);
186
+
187
+ return s;
188
+
189
+ }
190
+
191
+
192
+
193
+ //標準出力から行列を読み込み、別のメモリに記憶しておく
194
+
195
+ SMATRIX *smatrix_read() {
196
+
197
+ int i, n, m, x, y, k=0;
198
+
199
+ double v;
200
+
201
+ SMATRIX *s;
202
+
203
+ int test[] = { 2,3, 1,1,1, /*2,1,2*/ 1,2,4, 2,2,5, 3,2,6, 3,1,3, }; //テストデータ
204
+
205
+
206
+
207
+ n = test[k++]; //scanf("%d",&n);
208
+
209
+ m = test[k++]; //scanf("%d",&m);
210
+
211
+ s = smatrix_new(n, m);
212
+
213
+ for (i=0; i<(sizeof(test)/sizeof(int)-2)/3; i++) {
214
+
215
+ x = test[k++]; //scanf("%d",&s->a[i].j);
216
+
217
+ y = test[k++];
218
+
219
+ v = test[k++]; //scanf("%lf",&s->a[i].v);
220
+
221
+ slist_put(&s->a, x, y, v);
222
+
223
+ }
224
+
225
+ return s;
226
+
227
+ }
228
+
229
+
230
+
231
+ //疎行列の転置を作成・出力
232
+
233
+ SMATRIX *smatrix_transpose(SMATRIX *s) {
234
+
235
+ SLOBJ *p;
236
+
237
+ SMATRIX *t;
238
+
239
+
240
+
241
+ t = smatrix_new(s->m, s->n);
242
+
243
+ for(p=s->a.next; p!=NULL; p=p->next) {
244
+
167
- o = o->next; p = o->next; q = p->next; //
245
+ slist_put(&t->a, p->y, p->x, p->v); //行列変換
246
+
168
-
247
+ }
248
+
249
+ return t;
250
+
251
+ }
252
+
253
+
254
+
255
+ //疎行列をプリント
256
+
257
+ void smatrix_print(char *label, SMATRIX *s) {
258
+
169
- if(q == NULL) slist->last = p;
259
+ if(label != NULL) printf("%s\n", label);
260
+
261
+ printf("%d %d\n", s->n, s->m);
262
+
263
+
264
+
265
+ for(int y=1; y<=s->n; y++) {
266
+
267
+ for(int x=1; x<=s->m; x++) {
268
+
269
+ printf("(%d,%d)=%lf%s", x, y, slist_get(&s->a,x,y), x==s->m?"\n":" ");
170
270
 
171
271
  }
172
272
 
173
- t = p;
174
-
175
- } while(changed);
176
-
177
- }
178
-
179
-
180
-
181
- //リストを解放
182
-
183
- void slist_clear(SLIST *slist) {
184
-
185
- SLOBJ *p, *q;
186
-
187
- for(p=slist->next; p!=NULL; p=q) {
188
-
189
- q = p->next;
190
-
191
- free(p);
192
-
193
- }
194
-
195
- slist_init(slist);
196
-
197
- }
198
-
199
-
200
-
201
- //疎行列の構造体
202
-
203
- typedef struct {
204
-
205
- int n, m;
206
-
207
- SLIST a;
208
-
209
- } SMATRIX;
210
-
211
-
212
-
213
- //新しい疎行列を作成
214
-
215
- SMATRIX *smatrix_new(int n, int m) {
216
-
217
- SMATRIX *s;
218
-
219
-
220
-
221
- s = (SMATRIX *)malloc(sizeof(SMATRIX));
222
-
223
- s->n = n;
224
-
225
- s->m = m;
226
-
227
- slist_init(&s->a);
228
-
229
- return s;
230
-
231
- }
232
-
233
-
234
-
235
- //標準出力から行列を読み込み、別のメモリに記憶しておく
236
-
237
- SMATRIX *smatrix_read() {
238
-
239
- int i, n, m, x, y, k=0;
240
-
241
- double v;
242
-
243
- SMATRIX *s;
244
-
245
- int test[] = { 2,3, 1,1,1, /*2,1,2*/ 1,2,4, 2,2,5, 3,2,6, 3,1,3, }; //テストデータ
246
-
247
-
248
-
249
- n = test[k++]; //scanf("%d",&n);
250
-
251
- m = test[k++]; //scanf("%d",&m);
252
-
253
- s = smatrix_new(n, m);
254
-
255
- for (i=0; i<(sizeof(test)/sizeof(int)-2)/3; i++) {
256
-
257
- x = test[k++]; //scanf("%d",&s->a[i].j);
258
-
259
- y = test[k++];
260
-
261
- v = test[k++]; //scanf("%lf",&s->a[i].v);
262
-
263
- slist_append(&s->a, x, y, v);
264
-
265
- }
266
-
267
- return s;
268
-
269
- }
270
-
271
-
272
-
273
- //疎行列の転置を作成・出力
274
-
275
- SMATRIX *smatrix_transpose(SMATRIX *s) {
276
-
277
- SLOBJ *p;
278
-
279
- SMATRIX *t;
280
-
281
-
282
-
283
- t = smatrix_new(s->m, s->n);
284
-
285
- for(p=s->a.next; p!=NULL; p=p->next) {
286
-
287
- slist_append(&t->a, p->y, p->x, p->v); //行列変換
288
-
289
- }
290
-
291
- return t;
292
-
293
- }
294
-
295
-
296
-
297
- //疎行列をプリント
298
-
299
- void smatrix_print(char *label, SMATRIX *s) {
300
-
301
- double v;
302
-
303
- SLOBJ *p;
304
-
305
-
306
-
307
- if(label != NULL) printf("%s\n", label);
308
-
309
- printf("%d %d\n", s->n, s->m);
310
-
311
-
312
-
313
- slist_sort(&s->a);
314
-
315
- p = s->a.next;
316
-
317
- for(int y=1; y<=s->n; y++) {
318
-
319
- for(int x=1; x<=s->m; x++) {
320
-
321
- if(p != NULL && p->x == x && p->y == y) {
322
-
323
- v = p->v;
324
-
325
- p = p->next;
326
-
327
- } else {
328
-
329
- v = 0.0;
330
-
331
- }
332
-
333
- printf("(%d,%d)=%lf%s", x, y, v, x==s->m?"\n":" ");
334
-
335
- }
336
-
337
273
  }
338
274
 
339
275
  }

2

コード見直し

2020/04/27 09:33

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -8,6 +8,16 @@
8
8
 
9
9
  テストを簡単にするため, smatrix_read を改造しています.
10
10
 
11
+
12
+
13
+ #修正
14
+
15
+ リストを使うようにし, 2次元で動作するようにしました.
16
+
17
+ データが無い所を 0 表示するようにしました.
18
+
19
+ ソート部分がテキトウかもしれません.
20
+
11
21
  ```c
12
22
 
13
23
  #include <stdio.h>
@@ -20,7 +30,9 @@
20
30
 
21
31
  typedef struct slobj {
22
32
 
33
+ struct slobj *next; //必ず構造体の先頭にすること
34
+
23
- int j;
35
+ int x, y;
24
36
 
25
37
  double v;
26
38
 
@@ -28,13 +40,171 @@
28
40
 
29
41
 
30
42
 
43
+ //新しい要素を作成
44
+
45
+ SLOBJ *slobj_new(int x, int y, double v){
46
+
47
+ SLOBJ *p;
48
+
49
+
50
+
51
+ p = (SLOBJ *)malloc(sizeof(SLOBJ));
52
+
53
+ p->next = NULL;
54
+
55
+ p->x = x;
56
+
57
+ p->y = y;
58
+
59
+ p->v = v;
60
+
61
+ return p;
62
+
63
+ }
64
+
65
+
66
+
67
+ //リストの構造体
68
+
69
+ typedef struct slist {
70
+
71
+ SLOBJ *next; //必ず構造体の先頭にすること
72
+
73
+ SLOBJ *last;
74
+
75
+ } SLIST;
76
+
77
+
78
+
79
+ //リスト初期化
80
+
81
+ void slist_init(SLIST *slist) {
82
+
83
+ slist->next = NULL;
84
+
85
+ slist->last = (SLOBJ *)slist;
86
+
87
+ }
88
+
89
+
90
+
91
+ //リストに追加
92
+
93
+ void slist_append(SLIST *slist, int x, int y, double v) {
94
+
95
+ SLOBJ *p;
96
+
97
+
98
+
99
+ p = slobj_new(x, y, v);
100
+
101
+ slist->last->next = p;
102
+
103
+ slist->last = p;
104
+
105
+ }
106
+
107
+
108
+
109
+ //リストをカウント
110
+
111
+ int slist_count(SLIST *slist) {
112
+
113
+ int count;
114
+
115
+ SLOBJ *p;
116
+
117
+
118
+
119
+ count = 0;
120
+
121
+ for(p=slist->next; p!=NULL; p=p->next) count++;
122
+
123
+ return count;
124
+
125
+ }
126
+
127
+
128
+
129
+ //リストをソート
130
+
131
+ void slist_sort(SLIST *slist) {
132
+
133
+ SLOBJ *o, *p, *q, *t;
134
+
135
+ int count, changed;
136
+
137
+
138
+
139
+ count = slist_count(slist);
140
+
141
+ if(count <= 1) return;
142
+
143
+
144
+
145
+ t = NULL;
146
+
147
+ do { //バブル
148
+
149
+ changed = 0; //フラグクリア
150
+
151
+ o = (SLOBJ *)slist;
152
+
153
+ p = o->next;
154
+
155
+ q = p->next;
156
+
157
+ while(q != t) {
158
+
159
+ if(p->y > q->y || (p->y == q->y && p->x > q->x)) { //p>q
160
+
161
+ p->next = q->next; q->next = p; o->next = q; //入れ替え
162
+
163
+ changed = 1; //フラグセット
164
+
165
+ }
166
+
167
+ o = o->next; p = o->next; q = p->next; //次
168
+
169
+ if(q == NULL) slist->last = p;
170
+
171
+ }
172
+
173
+ t = p;
174
+
175
+ } while(changed);
176
+
177
+ }
178
+
179
+
180
+
181
+ //リストを解放
182
+
183
+ void slist_clear(SLIST *slist) {
184
+
185
+ SLOBJ *p, *q;
186
+
187
+ for(p=slist->next; p!=NULL; p=q) {
188
+
189
+ q = p->next;
190
+
191
+ free(p);
192
+
193
+ }
194
+
195
+ slist_init(slist);
196
+
197
+ }
198
+
199
+
200
+
31
201
  //疎行列の構造体
32
202
 
33
203
  typedef struct {
34
204
 
35
205
  int n, m;
36
206
 
37
- SLOBJ *a;
207
+ SLIST a;
38
208
 
39
209
  } SMATRIX;
40
210
 
@@ -54,7 +224,7 @@
54
224
 
55
225
  s->m = m;
56
226
 
57
- s->a = (SLOBJ *)malloc(sizeof(SLOBJ) * n*m);
227
+ slist_init(&s->a);
58
228
 
59
229
  return s;
60
230
 
@@ -66,11 +236,13 @@
66
236
 
67
237
  SMATRIX *smatrix_read() {
68
238
 
69
- int i, n, m, k=0;
239
+ int i, n, m, x, y, k=0;
240
+
241
+ double v;
70
242
 
71
243
  SMATRIX *s;
72
244
 
73
- int test[] = { 2,3, 1,1, 2,2, 3,3, 1,4, 2,5, 3,6 }; //テストデータ
245
+ int test[] = { 2,3, 1,1,1, /*2,1,2*/ 1,2,4, 2,2,5, 3,2,6, 3,1,3, }; //テストデータ
74
246
 
75
247
 
76
248
 
@@ -80,11 +252,15 @@
80
252
 
81
253
  s = smatrix_new(n, m);
82
254
 
83
- for (i=0; i<n*m; i++) {
255
+ for (i=0; i<(sizeof(test)/sizeof(int)-2)/3; i++) {
84
-
256
+
85
- s->a[i].j = test[k++]; //scanf("%d",&s->a[i].j);
257
+ x = test[k++]; //scanf("%d",&s->a[i].j);
258
+
86
-
259
+ y = test[k++];
260
+
87
- s->a[i].v = test[k++]; //scanf("%lf",&s->a[i].v);
261
+ v = test[k++]; //scanf("%lf",&s->a[i].v);
262
+
263
+ slist_append(&s->a, x, y, v);
88
264
 
89
265
  }
90
266
 
@@ -98,8 +274,6 @@
98
274
 
99
275
  SMATRIX *smatrix_transpose(SMATRIX *s) {
100
276
 
101
- int i;
102
-
103
277
  SLOBJ *p;
104
278
 
105
279
  SMATRIX *t;
@@ -108,13 +282,9 @@
108
282
 
109
283
  t = smatrix_new(s->m, s->n);
110
284
 
111
- for (i=0; i<s->n*s->m; i++) {
285
+ for(p=s->a.next; p!=NULL; p=p->next) {
112
-
286
+
113
- p = &t->a[(i%s->m) * t->m + (i/s->m)];
287
+ slist_append(&t->a, p->y, p->x, p->v); //行列変換
114
-
115
- p->j = i/s->m + 1;
116
-
117
- p->v = s->a[i].v;
118
288
 
119
289
  }
120
290
 
@@ -128,7 +298,9 @@
128
298
 
129
299
  void smatrix_print(char *label, SMATRIX *s) {
130
300
 
131
- int i;
301
+ double v;
302
+
303
+ SLOBJ *p;
132
304
 
133
305
 
134
306
 
@@ -136,11 +308,31 @@
136
308
 
137
309
  printf("%d %d\n", s->n, s->m);
138
310
 
311
+
312
+
313
+ slist_sort(&s->a);
314
+
315
+ p = s->a.next;
316
+
317
+ for(int y=1; y<=s->n; y++) {
318
+
139
- for(i=0; i<s->n*s->m; i++) {
319
+ for(int x=1; x<=s->m; x++) {
140
-
320
+
141
- printf("%d %lf%s", s->a[i].j, s->a[i].v,
321
+ if(p != NULL && p->x == x && p->y == y) {
322
+
142
-
323
+ v = p->v;
324
+
325
+ p = p->next;
326
+
327
+ } else {
328
+
329
+ v = 0.0;
330
+
331
+ }
332
+
143
- i%s->m==s->m-1?"\n":" ");
333
+ printf("(%d,%d)=%lf%s", x, y, v, x==s->m?"\n":" ");
334
+
335
+ }
144
336
 
145
337
  }
146
338
 
@@ -150,7 +342,7 @@
150
342
 
151
343
  void smatrix_free(SMATRIX *s) {
152
344
 
153
- free(s->a);
345
+ slist_clear(&s->a);
154
346
 
155
347
  free(s);
156
348
 
@@ -183,3 +375,25 @@
183
375
  }
184
376
 
185
377
  ```
378
+
379
+ ```plain text
380
+
381
+ A:
382
+
383
+ 2 3
384
+
385
+ (1,1)=1.000000 (2,1)=0.000000 (3,1)=3.000000
386
+
387
+ (1,2)=4.000000 (2,2)=5.000000 (3,2)=6.000000
388
+
389
+ B:
390
+
391
+ 3 2
392
+
393
+ (1,1)=1.000000 (2,1)=4.000000
394
+
395
+ (1,2)=0.000000 (2,2)=5.000000
396
+
397
+ (1,3)=3.000000 (2,3)=6.000000
398
+
399
+ ```

1

説明変更

2020/04/27 09:17

投稿

jimbe
jimbe

スコア12659

test CHANGED
@@ -4,13 +4,9 @@
4
4
 
5
5
  ということで, マトリクス生成時に大きさが決まっているのでリストにする必要が無いようですし, 実体とポインタが混在して分かり難く感じましたので, リスト関係を消し, SMATRIX の malloc をするようにしてみました.
6
6
 
7
- れなら解放抜けはし難いと思います.
7
+ 大きな行列で無ければのほうが解放抜けはし難いと思います.
8
8
 
9
9
  テストを簡単にするため, smatrix_read を改造しています.
10
-
11
-
12
-
13
- ...SLOBJ.j は"列番号"として表示しているだけのようですが構造体内に要るのでしょうか.
14
10
 
15
11
  ```c
16
12