競技プログラミング風 標準C++ライブラリ入門【第11回】
今回も、標準C++ライブラリの基本をマスターするための競技プログラミング風問題を解いていただこう。
問題を理解したら、テストコードをコンパイル・実行していただきたい。そのままだと実行時に「NG」が表示される。 コードを完成させ、「Good Job!」を表示させてすっきりしてほしい。グッドラック!
目次
Nの倍数を0に置換(難易度:★★☆☆☆)
引数で渡された vector<int>& lst の各要素が第2引数Nの倍数の場合は0に置換する関数 void replaceNxTo0(vector<int>& lst, int N) を実装しなさい
例えば、lst: {3, 1, 4, 1, 5, 9, 2, 6}, N: 2 の場合、lst は {3, 1, 0, 1, 5, 9, 0, 0} となる。
ただし、N>0 とし、Nが0以下の場合は、何も処理を行わないものとする。
#include <iostream> // 標準入出力ライブラリ #include <algorithm> #include <vector> using namespace std; // std 名前空間使用 #define DO_TEST(exp) do_test(exp, __LINE__) void do_test(bool b, int line) { if( b ) return; // OK cout << "\nNG at line " << line << "\n"; exit(1); } void replaceNxTo0(vector<int>& lst, int N) { // ToDo: 標準関数を使い、ここを書き換えて、Nの倍数のlst要素を0に置換する } int main() { vector<int> lst1 = {3, 1, 4, 1, 5, 9, 2, 6}; replaceNxTo0(lst1, 2); DO_TEST( lst1 == vector<int>({3, 1, 0, 1, 5, 9, 0, 0}) ); cout << "\nGood Job!\n"; return 0; }
スマートポインタ(難易度:★★☆☆☆)
テストコードの「ここから」「ここまで」の部分を修正して、lst を resize() で縮小するとオブジェクトが自動的に破棄されるようにしなさい。
テストコードで定義している CTest クラスは、コンストラクタがコールされるとカウンタをインクリメントし、 デストラクタがコールされるとカウンタをデクリメントするようになっている。
#include <iostream> // 標準入出力ライブラリ #include <vector> //#include <memory> using namespace std; // std 名前空間使用 #define DO_TEST(exp) do_test(exp, __LINE__) void do_test(bool b, int line) { if (b) return; // OK cout << "\nNG at line " << line << "\n"; exit(1); } int g_objCount = 0; // オブジェクト数 struct CTest { CTest() { ++g_objCount; } // オブジェクト数をインクリメント ~CTest() { --g_objCount; } // オブジェクト数をデクリメント }; int main() { const int N_OBJECT = 10; const int N_RESIZED = 7; //-----ここから----- // ToDo: 以下を書き換え、lst を resize() で縮小するとオブジェクトが自動的に破棄されるよう修正 vector<CTest*> lst; for (int i = 0; i != N_OBJECT; ++i) lst.push_back(new CTest); //-----ここまで----- DO_TEST(g_objCount == N_OBJECT); lst.resize(N_RESIZED); // lst を縮小 DO_TEST(g_objCount == N_RESIZED); cout << "\nGood Job!\n"; return 0; }
マルチスレッド(難易度:★★☆☆☆)
テストコードの ToDo 部分を書き換え、複数の関数 foo(char) が同時並行的に実行されるようにしなさい。
テストコードをそのまま実行すると、foo(‘A’) で「AAAAAAAAAA」が、foo(‘Z’) で「ZZZZZZZZZZ」が表示されるので、 トータルで「AAAAAAAAAAZZZZZZZZZZ」と表示され。 それらを同時並行的に実行すると「AZAZAZAZAZAZAZAZAZAZ」のように ‘A’ と ‘Z’ が混ざって表示される (ただし、このようにキレイに交互に混ざるとは限らない)。
#include <iostream> // 標準入出力ライブラリ #include <thread> using namespace std; // std 名前空間使用 #define DO_TEST(exp) do_test(exp, __LINE__) void do_test(bool b, int line) { if( b ) return; // OK cout << "\nNG at line " << line << "\n"; exit(1); } string g_out; void foo(char ch) { for(int i = 0; i != 10; ++i) { g_out += ch; cout << ch; std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 100ミリ秒ウェイト } } int main() { //-----ここから----- // ToDo: マルチスレッドで foo('A'), foo('Z') を起動するよう修正 foo('A'); foo('Z'); // ToDo: マルチスレッドで起動された foo('A'), foo('Z') が終了するまで待つよう修正 //-----ここまで----- DO_TEST(g_out != "AAAAAAAAAAZZZZZZZZZZ"); cout << "\nGood Job!\n"; return 0; }
競技プログラミング風 標準C++ライブラリ入門 連載目次リンク
![]() |
筆者:津田伸秀 プロフィール:テニス・オセロ・ボードゲーム・パズル類が趣味の年齢不詳のおじさん。 自宅研究員(主席)。vi と C++が好き。迷走中・・・ ボードゲーム・パズル系アプリ開発・リリースしてます。 |