回答編集履歴
3
可変長配列を使わないコード
answer
CHANGED
@@ -39,4 +39,21 @@
|
|
39
39
|
}
|
40
40
|
}
|
41
41
|
```
|
42
|
-
もちろん、コンパイル時には最適化オプションを指定してください。
|
42
|
+
もちろん、コンパイル時には最適化オプションを指定してください。
|
43
|
+
|
44
|
+
**追記3**
|
45
|
+
> 今回はN=64~2048の2の冪乗の数で計測しようとしています.
|
46
|
+
|
47
|
+
それなら、可変長配列なんか使わず、次のようにすれば速くなるのではありませんか?
|
48
|
+
```
|
49
|
+
#define N 64
|
50
|
+
|
51
|
+
void naive_rotate(int n, int src[N][N], dst[N][N])
|
52
|
+
{
|
53
|
+
for (int i = 0; i < N; i++)
|
54
|
+
for (int j = 0; j < N; j++)
|
55
|
+
dst[i][j] = src[j][N-1-i];
|
56
|
+
}
|
57
|
+
```
|
58
|
+
引数の int n は使っていないので不要ですが、呼び出し元を変更しないで済む
|
59
|
+
ように残しています。
|
2
ポインタを使うコードを追加
answer
CHANGED
@@ -23,4 +23,20 @@
|
|
23
23
|
ただ、`dst[n-1-j][i] = src[i][j];` のように
|
24
24
|
dst を飛び飛びにして、src を連続にするよりも、
|
25
25
|
`dst[i][j] = src[j][n-1-i];` のように
|
26
|
-
dst を連続にして、src を飛び飛びにするほうがほんのわずか速いかもしれません。
|
26
|
+
dst を連続にして、src を飛び飛びにするほうがほんのわずか速いかもしれません。
|
27
|
+
|
28
|
+
**追記2**
|
29
|
+
ポインタにしてみました。添字の計算で掛け算がなくなり速くなるかもしれません。
|
30
|
+
配列のアドレスより前を指すので規格違反ですが、そこはアクセスしません。
|
31
|
+
```C
|
32
|
+
void naive_rotate(int n, int src[n][n], int dst[n][n])
|
33
|
+
{
|
34
|
+
int *dp = dst[0], *sp = src[0] - 1, m = n*n + 1;
|
35
|
+
for (int i = 0; i < n; i++) {
|
36
|
+
for (int j = 0; j < n; j++)
|
37
|
+
*dp++ = *(sp += n);
|
38
|
+
sp -= m;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
```
|
42
|
+
もちろん、コンパイル時には最適化オプションを指定してください。
|
1
転置ではなく回転についての説明
answer
CHANGED
@@ -15,4 +15,12 @@
|
|
15
15
|
ループ回数の減少のほうが大きく効いてくるでしょう。
|
16
16
|
|
17
17
|
配列をポインタに置き換えると高速になることがありますが、
|
18
|
-
最近のコンパイラは最適化でこれを勝手にやってくれたりします。
|
18
|
+
最近のコンパイラは最適化でこれを勝手にやってくれたりします。
|
19
|
+
|
20
|
+
**追記**
|
21
|
+
回転なら愚直に (n*n)回ループするしかないでしょう。
|
22
|
+
|
23
|
+
ただ、`dst[n-1-j][i] = src[i][j];` のように
|
24
|
+
dst を飛び飛びにして、src を連続にするよりも、
|
25
|
+
`dst[i][j] = src[j][n-1-i];` のように
|
26
|
+
dst を連続にして、src を飛び飛びにするほうがほんのわずか速いかもしれません。
|