回答編集履歴
3
可変長配列を使わないコード
test
CHANGED
@@ -81,3 +81,37 @@
|
|
81
81
|
```
|
82
82
|
|
83
83
|
もちろん、コンパイル時には最適化オプションを指定してください。
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
**追記3**
|
88
|
+
|
89
|
+
> 今回はN=64~2048の2の冪乗の数で計測しようとしています.
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
それなら、可変長配列なんか使わず、次のようにすれば速くなるのではありませんか?
|
94
|
+
|
95
|
+
```
|
96
|
+
|
97
|
+
#define N 64
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
void naive_rotate(int n, int src[N][N], dst[N][N])
|
102
|
+
|
103
|
+
{
|
104
|
+
|
105
|
+
for (int i = 0; i < N; i++)
|
106
|
+
|
107
|
+
for (int j = 0; j < N; j++)
|
108
|
+
|
109
|
+
dst[i][j] = src[j][N-1-i];
|
110
|
+
|
111
|
+
}
|
112
|
+
|
113
|
+
```
|
114
|
+
|
115
|
+
引数の int n は使っていないので不要ですが、呼び出し元を変更しないで済む
|
116
|
+
|
117
|
+
ように残しています。
|
2
ポインタを使うコードを追加
test
CHANGED
@@ -49,3 +49,35 @@
|
|
49
49
|
`dst[i][j] = src[j][n-1-i];` のように
|
50
50
|
|
51
51
|
dst を連続にして、src を飛び飛びにするほうがほんのわずか速いかもしれません。
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
**追記2**
|
56
|
+
|
57
|
+
ポインタにしてみました。添字の計算で掛け算がなくなり速くなるかもしれません。
|
58
|
+
|
59
|
+
配列のアドレスより前を指すので規格違反ですが、そこはアクセスしません。
|
60
|
+
|
61
|
+
```C
|
62
|
+
|
63
|
+
void naive_rotate(int n, int src[n][n], int dst[n][n])
|
64
|
+
|
65
|
+
{
|
66
|
+
|
67
|
+
int *dp = dst[0], *sp = src[0] - 1, m = n*n + 1;
|
68
|
+
|
69
|
+
for (int i = 0; i < n; i++) {
|
70
|
+
|
71
|
+
for (int j = 0; j < n; j++)
|
72
|
+
|
73
|
+
*dp++ = *(sp += n);
|
74
|
+
|
75
|
+
sp -= m;
|
76
|
+
|
77
|
+
}
|
78
|
+
|
79
|
+
}
|
80
|
+
|
81
|
+
```
|
82
|
+
|
83
|
+
もちろん、コンパイル時には最適化オプションを指定してください。
|
1
転置ではなく回転についての説明
test
CHANGED
@@ -33,3 +33,19 @@
|
|
33
33
|
配列をポインタに置き換えると高速になることがありますが、
|
34
34
|
|
35
35
|
最近のコンパイラは最適化でこれを勝手にやってくれたりします。
|
36
|
+
|
37
|
+
|
38
|
+
|
39
|
+
**追記**
|
40
|
+
|
41
|
+
回転なら愚直に (n*n)回ループするしかないでしょう。
|
42
|
+
|
43
|
+
|
44
|
+
|
45
|
+
ただ、`dst[n-1-j][i] = src[i][j];` のように
|
46
|
+
|
47
|
+
dst を飛び飛びにして、src を連続にするよりも、
|
48
|
+
|
49
|
+
`dst[i][j] = src[j][n-1-i];` のように
|
50
|
+
|
51
|
+
dst を連続にして、src を飛び飛びにするほうがほんのわずか速いかもしれません。
|