このセクションでは、部分文字列一致プログラムで parallel_for テンプレートを使用する基本的な例を説明します。 文字列の各位置で、プログラムは文字列の他の部分と一致する最も大きな部分文字列の長さと位置を表示します。
例として、文字列 babba を考えてみます。位置 0 で開始すると、文字列で一致する最大の部分文字列は位置 3 の ba です。
インテル® TBB の examples/GettingStarted フォルダーに含まれているこのプログラムの完全バージョンを参照するか、あるいは、次の説明に従ってアプリケーションを作成してみてください。このセクションでは、各ステップに追加するコードを太字で表示しています。行番号は、最終的なサンプルの行番号を示しています。
サンプルコードの作成手順:
07: using namespace tbb; 36: int main() { 50: return 0; 51: }
01: #include <iostream> 02: #include <string> 07: using namespace tbb; 08: using namespace std; 09: static const size_t N = 23; 36: int main() { 38: string str[N] = { string("a"), string("b") }; 39: for (size_t i = 2; i < N; ++i) str[i] = str[i-1]+str[i-2]; 40: string &to_scan = str[N-1]; 41: size_t num_elem = to_scan.size(); 42: size_t *max = new size_t[num_elem]; 43: size_t *pos = new size_t[num_elem]; 44—45: // add code to populate max and pos here 46: for (size_t i = 0; i < num_elem; ++i) 47: cout << " " << max[i] << "(" << pos[i] << ")" << endl; 48: delete[] pos; 49: delete[] max; 50: return 0; 51: }
呼び出しの第 1 引数は、反復空間を示す blocked_range オブジェクトです。
blocked_range は、インテル® TBB ライブラリーによって提供されるテンプレート・クラスです。 コンストラクターの引数は、次のようになります。
parallel_for 関数の第 2 引数は、各サブ範囲に適用する関数オブジェクトです。
01: #include <iostream> 02: #include <string> 05: #include "tbb/parallel_for.h" 06: #include "tbb/blocked_range.h" 07: using namespace tbb; 08: using namespace std; 09: static const size_t N = 23; 36: int main() { 38: string str[N] = { string("a"), string("b") }; 39: for (size_t i = 2; i < N; ++i) str[i] = str[i-1]+str[i-2]; 40: string &to_scan = str[N-1]; 41: size_t num_elem = to_scan.size(); 42: size_t *max = new size_t[num_elem]; 43: size_t *pos = new size_t[num_elem]; 44: parallel_for(blocked_range<size_t>(0, num_elem ), 45: SubStringFinder( to_scan, max, pos ) ); 46: for (size_t i = 0; i < num_elem; ++i) 47: cout << " " << max[i] << "(" << pos[i] << ")" << endl; 48: delete[] pos; 49: delete[] max; 50: return 0; 51: }
ランタイムに、parallel_for テンプレートは範囲を複数のサブ範囲に分割して、各サブ範囲で SubStringFinder 関数オブジェクトを呼び出します。
行 16 の r.begin() はサブ範囲の開始位置を、r.end() はサブ範囲の終了位置を返します。
01: #include <iostream> 02: #include <string> 03: #include <algorithm> 04: #include "tbb/parallel_for.h" 05: #include "tbb/blocked_range.h" 07: using namespace tbb; 08: using namespace std; 09: static const size_t N = 23; 10: class SubStringFinder { 11: const string str; 12: size_t *max_array; 13: size_t *pos_array; 14: public: 15: void operator() ( const blocked_range<size_t>& r ) const { 16: for ( size_t i = r.begin(); i != r.end(); ++i ) { 17: size_t max_size = 0, max_pos = 0; 18: for (size_t j = 0; j < str.size(); ++j) 19: if (j != i) { 20: size_t limit = str.size()-max(i,j); 21: for (size_t k = 0; k < limit; ++k) { 22: if (str[i + k] != str[j + k]) break; 23: if (k > max_size) { 24: max_size = k; 25: max_pos = j; 26: } 27: } 28: } 29: max_array[i] = max_size; 30: pos_array[i] = max_pos; 31: } 32: } 33: SubStringFinder(string &s, size_t *m, size_t *p) : 34: str(s), max_array(m), pos_array(p) { } 35: }; 36—51: // 行番号 36 から開始する関数 main をここに記述