回答編集履歴
3
ソートを止め, put/get で検索
answer
CHANGED
@@ -5,9 +5,8 @@
|
|
5
5
|
テストを簡単にするため, smatrix_read を改造しています.
|
6
6
|
|
7
7
|
#修正
|
8
|
-
リストを使うようにし, 2次元
|
8
|
+
リストを使うように戻し, 2次元的に動作するようにしました.
|
9
9
|
データが無い所を 0 表示するようにしました.
|
10
|
-
ソート部分がテキトウかもしれません.
|
11
10
|
```c
|
12
11
|
#include <stdio.h>
|
13
12
|
#include <stdlib.h>
|
@@ -37,58 +36,38 @@
|
|
37
36
|
SLOBJ *last;
|
38
37
|
} SLIST;
|
39
38
|
|
40
|
-
//
|
39
|
+
//初期化
|
41
40
|
void slist_init(SLIST *slist) {
|
42
41
|
slist->next = NULL;
|
43
42
|
slist->last = (SLOBJ *)slist;
|
44
43
|
}
|
45
44
|
|
46
|
-
//
|
45
|
+
//書き換えor追加
|
47
|
-
void
|
46
|
+
void slist_put(SLIST *slist, int x, int y, double v) {
|
48
47
|
SLOBJ *p;
|
49
48
|
|
49
|
+
for(p=slist->next; p!=NULL; p=p->next) {
|
50
|
+
if(p->x == x && p->y == y) {
|
51
|
+
p->v = v;
|
52
|
+
return;
|
53
|
+
}
|
54
|
+
}
|
50
55
|
p = slobj_new(x, y, v);
|
51
56
|
slist->last->next = p;
|
52
57
|
slist->last = p;
|
53
58
|
}
|
54
59
|
|
55
|
-
//
|
60
|
+
//取り出し
|
56
|
-
|
61
|
+
double slist_get(SLIST *slist, int x, int y) {
|
57
|
-
int count;
|
58
62
|
SLOBJ *p;
|
59
63
|
|
60
|
-
count = 0;
|
61
|
-
for(p=slist->next; p!=NULL; p=p->next)
|
64
|
+
for(p=slist->next; p!=NULL; p=p->next) {
|
65
|
+
if(p->x == x && p->y == y) return p->v;
|
66
|
+
}
|
62
|
-
return
|
67
|
+
return 0.0;
|
63
68
|
}
|
64
69
|
|
65
|
-
//リストをソート
|
66
|
-
void slist_sort(SLIST *slist) {
|
67
|
-
SLOBJ *o, *p, *q, *t;
|
68
|
-
int count, changed;
|
69
|
-
|
70
|
-
count = slist_count(slist);
|
71
|
-
if(count <= 1) return;
|
72
|
-
|
73
|
-
t = NULL;
|
74
|
-
do { //バブル
|
75
|
-
changed = 0; //フラグクリア
|
76
|
-
o = (SLOBJ *)slist;
|
77
|
-
p = o->next;
|
78
|
-
q = p->next;
|
79
|
-
while(q != t) {
|
80
|
-
if(p->y > q->y || (p->y == q->y && p->x > q->x)) { //p>q
|
81
|
-
p->next = q->next; q->next = p; o->next = q; //入れ替え
|
82
|
-
changed = 1; //フラグセット
|
83
|
-
}
|
84
|
-
o = o->next; p = o->next; q = p->next; //次
|
85
|
-
if(q == NULL) slist->last = p;
|
86
|
-
}
|
87
|
-
t = p;
|
88
|
-
} while(changed);
|
89
|
-
}
|
90
|
-
|
91
|
-
//
|
70
|
+
//解放
|
92
71
|
void slist_clear(SLIST *slist) {
|
93
72
|
SLOBJ *p, *q;
|
94
73
|
for(p=slist->next; p!=NULL; p=q) {
|
@@ -129,7 +108,7 @@
|
|
129
108
|
x = test[k++]; //scanf("%d",&s->a[i].j);
|
130
109
|
y = test[k++];
|
131
110
|
v = test[k++]; //scanf("%lf",&s->a[i].v);
|
132
|
-
|
111
|
+
slist_put(&s->a, x, y, v);
|
133
112
|
}
|
134
113
|
return s;
|
135
114
|
}
|
@@ -141,30 +120,19 @@
|
|
141
120
|
|
142
121
|
t = smatrix_new(s->m, s->n);
|
143
122
|
for(p=s->a.next; p!=NULL; p=p->next) {
|
144
|
-
|
123
|
+
slist_put(&t->a, p->y, p->x, p->v); //行列変換
|
145
124
|
}
|
146
125
|
return t;
|
147
126
|
}
|
148
127
|
|
149
128
|
//疎行列をプリント
|
150
129
|
void smatrix_print(char *label, SMATRIX *s) {
|
151
|
-
double v;
|
152
|
-
SLOBJ *p;
|
153
|
-
|
154
130
|
if(label != NULL) printf("%s\n", label);
|
155
131
|
printf("%d %d\n", s->n, s->m);
|
156
132
|
|
157
|
-
slist_sort(&s->a);
|
158
|
-
p = s->a.next;
|
159
133
|
for(int y=1; y<=s->n; y++) {
|
160
134
|
for(int x=1; x<=s->m; x++) {
|
161
|
-
if(p != NULL && p->x == x && p->y == y) {
|
162
|
-
v = p->v;
|
163
|
-
p = p->next;
|
164
|
-
} else {
|
165
|
-
v = 0.0;
|
166
|
-
}
|
167
|
-
printf("(%d,%d)=%lf%s", x, y,
|
135
|
+
printf("(%d,%d)=%lf%s", x, y, slist_get(&s->a,x,y), x==s->m?"\n":" ");
|
168
136
|
}
|
169
137
|
}
|
170
138
|
}
|
2
コード見直し
answer
CHANGED
@@ -3,20 +3,105 @@
|
|
3
3
|
ということで, マトリクス生成時に大きさが決まっているのでリストにする必要が無いようですし, 実体とポインタが混在して分かり難く感じましたので, リスト関係を消し, SMATRIX の malloc をするようにしてみました.
|
4
4
|
大きな行列で無ければこのほうが解放抜けはし難いと思います.
|
5
5
|
テストを簡単にするため, smatrix_read を改造しています.
|
6
|
+
|
7
|
+
#修正
|
8
|
+
リストを使うようにし, 2次元で動作するようにしました.
|
9
|
+
データが無い所を 0 表示するようにしました.
|
10
|
+
ソート部分がテキトウかもしれません.
|
6
11
|
```c
|
7
12
|
#include <stdio.h>
|
8
13
|
#include <stdlib.h>
|
9
14
|
|
10
15
|
//要素の構造体
|
11
16
|
typedef struct slobj {
|
17
|
+
struct slobj *next; //必ず構造体の先頭にすること
|
12
|
-
int
|
18
|
+
int x, y;
|
13
19
|
double v;
|
14
20
|
} SLOBJ;
|
15
21
|
|
22
|
+
//新しい要素を作成
|
23
|
+
SLOBJ *slobj_new(int x, int y, double v){
|
24
|
+
SLOBJ *p;
|
25
|
+
|
26
|
+
p = (SLOBJ *)malloc(sizeof(SLOBJ));
|
27
|
+
p->next = NULL;
|
28
|
+
p->x = x;
|
29
|
+
p->y = y;
|
30
|
+
p->v = v;
|
31
|
+
return p;
|
32
|
+
}
|
33
|
+
|
34
|
+
//リストの構造体
|
35
|
+
typedef struct slist {
|
36
|
+
SLOBJ *next; //必ず構造体の先頭にすること
|
37
|
+
SLOBJ *last;
|
38
|
+
} SLIST;
|
39
|
+
|
40
|
+
//リスト初期化
|
41
|
+
void slist_init(SLIST *slist) {
|
42
|
+
slist->next = NULL;
|
43
|
+
slist->last = (SLOBJ *)slist;
|
44
|
+
}
|
45
|
+
|
46
|
+
//リストに追加
|
47
|
+
void slist_append(SLIST *slist, int x, int y, double v) {
|
48
|
+
SLOBJ *p;
|
49
|
+
|
50
|
+
p = slobj_new(x, y, v);
|
51
|
+
slist->last->next = p;
|
52
|
+
slist->last = p;
|
53
|
+
}
|
54
|
+
|
55
|
+
//リストをカウント
|
56
|
+
int slist_count(SLIST *slist) {
|
57
|
+
int count;
|
58
|
+
SLOBJ *p;
|
59
|
+
|
60
|
+
count = 0;
|
61
|
+
for(p=slist->next; p!=NULL; p=p->next) count++;
|
62
|
+
return count;
|
63
|
+
}
|
64
|
+
|
65
|
+
//リストをソート
|
66
|
+
void slist_sort(SLIST *slist) {
|
67
|
+
SLOBJ *o, *p, *q, *t;
|
68
|
+
int count, changed;
|
69
|
+
|
70
|
+
count = slist_count(slist);
|
71
|
+
if(count <= 1) return;
|
72
|
+
|
73
|
+
t = NULL;
|
74
|
+
do { //バブル
|
75
|
+
changed = 0; //フラグクリア
|
76
|
+
o = (SLOBJ *)slist;
|
77
|
+
p = o->next;
|
78
|
+
q = p->next;
|
79
|
+
while(q != t) {
|
80
|
+
if(p->y > q->y || (p->y == q->y && p->x > q->x)) { //p>q
|
81
|
+
p->next = q->next; q->next = p; o->next = q; //入れ替え
|
82
|
+
changed = 1; //フラグセット
|
83
|
+
}
|
84
|
+
o = o->next; p = o->next; q = p->next; //次
|
85
|
+
if(q == NULL) slist->last = p;
|
86
|
+
}
|
87
|
+
t = p;
|
88
|
+
} while(changed);
|
89
|
+
}
|
90
|
+
|
91
|
+
//リストを解放
|
92
|
+
void slist_clear(SLIST *slist) {
|
93
|
+
SLOBJ *p, *q;
|
94
|
+
for(p=slist->next; p!=NULL; p=q) {
|
95
|
+
q = p->next;
|
96
|
+
free(p);
|
97
|
+
}
|
98
|
+
slist_init(slist);
|
99
|
+
}
|
100
|
+
|
16
101
|
//疎行列の構造体
|
17
102
|
typedef struct {
|
18
103
|
int n, m;
|
19
|
-
|
104
|
+
SLIST a;
|
20
105
|
} SMATRIX;
|
21
106
|
|
22
107
|
//新しい疎行列を作成
|
@@ -26,55 +111,66 @@
|
|
26
111
|
s = (SMATRIX *)malloc(sizeof(SMATRIX));
|
27
112
|
s->n = n;
|
28
113
|
s->m = m;
|
29
|
-
s->a
|
114
|
+
slist_init(&s->a);
|
30
115
|
return s;
|
31
116
|
}
|
32
117
|
|
33
118
|
//標準出力から行列を読み込み、別のメモリに記憶しておく
|
34
119
|
SMATRIX *smatrix_read() {
|
35
|
-
int i, n, m, k=0;
|
120
|
+
int i, n, m, x, y, k=0;
|
121
|
+
double v;
|
36
122
|
SMATRIX *s;
|
37
|
-
int test[] = { 2,3, 1,1, 2,
|
123
|
+
int test[] = { 2,3, 1,1,1, /*2,1,2*/ 1,2,4, 2,2,5, 3,2,6, 3,1,3, }; //テストデータ
|
38
124
|
|
39
125
|
n = test[k++]; //scanf("%d",&n);
|
40
126
|
m = test[k++]; //scanf("%d",&m);
|
41
127
|
s = smatrix_new(n, m);
|
42
|
-
for (i=0; i<
|
128
|
+
for (i=0; i<(sizeof(test)/sizeof(int)-2)/3; i++) {
|
43
|
-
|
129
|
+
x = test[k++]; //scanf("%d",&s->a[i].j);
|
130
|
+
y = test[k++];
|
44
|
-
|
131
|
+
v = test[k++]; //scanf("%lf",&s->a[i].v);
|
132
|
+
slist_append(&s->a, x, y, v);
|
45
133
|
}
|
46
134
|
return s;
|
47
135
|
}
|
48
136
|
|
49
137
|
//疎行列の転置を作成・出力
|
50
138
|
SMATRIX *smatrix_transpose(SMATRIX *s) {
|
51
|
-
int i;
|
52
139
|
SLOBJ *p;
|
53
140
|
SMATRIX *t;
|
54
141
|
|
55
142
|
t = smatrix_new(s->m, s->n);
|
56
|
-
for
|
143
|
+
for(p=s->a.next; p!=NULL; p=p->next) {
|
57
|
-
|
144
|
+
slist_append(&t->a, p->y, p->x, p->v); //行列変換
|
58
|
-
p->j = i/s->m + 1;
|
59
|
-
p->v = s->a[i].v;
|
60
145
|
}
|
61
146
|
return t;
|
62
147
|
}
|
63
148
|
|
64
149
|
//疎行列をプリント
|
65
150
|
void smatrix_print(char *label, SMATRIX *s) {
|
66
|
-
|
151
|
+
double v;
|
152
|
+
SLOBJ *p;
|
67
153
|
|
68
154
|
if(label != NULL) printf("%s\n", label);
|
69
155
|
printf("%d %d\n", s->n, s->m);
|
156
|
+
|
157
|
+
slist_sort(&s->a);
|
158
|
+
p = s->a.next;
|
159
|
+
for(int y=1; y<=s->n; y++) {
|
70
|
-
|
160
|
+
for(int x=1; x<=s->m; x++) {
|
71
|
-
|
161
|
+
if(p != NULL && p->x == x && p->y == y) {
|
162
|
+
v = p->v;
|
163
|
+
p = p->next;
|
164
|
+
} else {
|
165
|
+
v = 0.0;
|
166
|
+
}
|
72
|
-
|
167
|
+
printf("(%d,%d)=%lf%s", x, y, v, x==s->m?"\n":" ");
|
168
|
+
}
|
73
169
|
}
|
74
170
|
}
|
75
171
|
|
76
172
|
void smatrix_free(SMATRIX *s) {
|
77
|
-
|
173
|
+
slist_clear(&s->a);
|
78
174
|
free(s);
|
79
175
|
}
|
80
176
|
|
@@ -90,4 +186,15 @@
|
|
90
186
|
smatrix_free(b);
|
91
187
|
return 0;
|
92
188
|
}
|
189
|
+
```
|
190
|
+
```plain text
|
191
|
+
A:
|
192
|
+
2 3
|
193
|
+
(1,1)=1.000000 (2,1)=0.000000 (3,1)=3.000000
|
194
|
+
(1,2)=4.000000 (2,2)=5.000000 (3,2)=6.000000
|
195
|
+
B:
|
196
|
+
3 2
|
197
|
+
(1,1)=1.000000 (2,1)=4.000000
|
198
|
+
(1,2)=0.000000 (2,2)=5.000000
|
199
|
+
(1,3)=3.000000 (2,3)=6.000000
|
93
200
|
```
|
1
説明変更
answer
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
> 根本的に
|
2
2
|
|
3
3
|
ということで, マトリクス生成時に大きさが決まっているのでリストにする必要が無いようですし, 実体とポインタが混在して分かり難く感じましたので, リスト関係を消し, SMATRIX の malloc をするようにしてみました.
|
4
|
-
|
4
|
+
大きな行列で無ければこのほうが解放抜けはし難いと思います.
|
5
5
|
テストを簡単にするため, smatrix_read を改造しています.
|
6
|
-
|
7
|
-
...SLOBJ.j は"列番号"として表示しているだけのようですが構造体内に要るのでしょうか.
|
8
6
|
```c
|
9
7
|
#include <stdio.h>
|
10
8
|
#include <stdlib.h>
|