昨日(id:toburau:20100302)のウェブの記事にあった"ループを使わずに配列の順序を逆にする"という問題。日記を書いていたときにはまったく解法を思いつかなかったけど、ふと再帰を使えばできるのではと思ったのでやってみた。
アルゴリズムは配列を半分に分けて、それぞれで再帰。そして分けた半分を入れ替えるというもの。試したソースは次の通り。このReverse()が逆にするアルゴリズムを実装した部分。
#include <iostream> using namespace std; static const int MAX = 100; void Reverse(int* p, int max) { if (max < 2) return; // 半分に分けて再帰 int half = max/2; int odd = max%2; Reverse(p, half); Reverse(p+half+odd, half); // 半分を入れ替え int* tmp = new int[half]; memcpy(tmp, p, sizeof(int)*half); memcpy(p, p+half+odd, sizeof(int)*half); memcpy(p+half+odd, tmp, sizeof(int)*half); delete[] tmp; } int main() { int Array[MAX]; for(int i=0; i<MAX; i++) Array[i] = i; for(int i=0; i<MAX; i++) cout << Array[i] << ' '; cout << endl; Reverse(Array, MAX); for(int i=0; i<MAX; i++) cout << Array[i] << ' '; cout << endl; return 0; }
アルゴリズムを思いついたときはすぐにできるのではと思ったけど、実際にコードを書き始めてみると結構大変だった。配列の個数が奇数の場合の処理や入れ替える部分などが手間取った。かかった時間はだいたい1時間くらい。
そういえば、intの配列で試したけど、テンプレートを使えば良かったのか。
一応、できたけど、これが正解かどうかはわからない。動作するという意味では正解だけど。