回答編集履歴

3

可変長配列を使わないコード

2021/07/25 13:48

投稿

kazuma-s
kazuma-s

スコア8224

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

ポインタを使うコードを追加

2021/07/25 13:48

投稿

kazuma-s
kazuma-s

スコア8224

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

転置ではなく回転についての説明

2021/07/24 15:33

投稿

kazuma-s
kazuma-s

スコア8224

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 を飛び飛びにするほうがほんのわずか速いかもしれません。