このページは、練習問題の解答例や解説のページです。
次のうち、結果が true になるものをすべて選んでください。a の値は 10、b の値は 20 とします。
1番は、論理AND演算子(&&
)を使って、2つの条件式をつないでいます(本編解説)。論理AND演算子は、まず左側のオペランド(a == 10
)を評価します。これは
true です。左側のオペランドが true
の場合にかぎって、右側のオペランド(b == 20
)の評価に進みます。こちらも
true なので、全体の結果は true になります。
2番も論理AND演算子を使っています。1番と同様に、左側のオペランド(a == 10
)を評価し、これは
true
になります。続いて、右側のオペランド(b == 10
)を評価します。こちらは
false になるので、全体の結果は false です。
3番は、論理OR演算子(||
)を使っています(本編解説)。論理OR演算子は、まず左側のオペランド(a != b
)を評価します。これは
true です。左側のオペランドが true であった時点で、全体の結果は true
に確定し、右側のオペランドは評価されません。
4番は、論理否定演算子(!
)を使っています(本編解説)。論理否定演算子は、条件式の結果を逆(true
なら false、false なら true)にします。条件式は (a == b)
で、これは false ですから、全体の結果は true
になります。なお、!(a == b)
という条件式は、a != b
と同じ意味です。
5番は、論理否定演算子を適用する対象が
(a == 10 || b == 10)
となっています。論理OR演算子のルールにしたがって、左側のオペランド(a == 10
)が評価され、これが
true なので、この条件式は true
であることが確定します。この結果を、論理否定演算子によって逆にするので、全体の結果は
false です。
6番は、論理OR演算子と論理AND演算子が混在しています。演算子の優先順位は、論理AND演算子のほうが高いため(本編解説)、この式は
a % 2 != 0 || (a == 10 && b == 20)
と同等です。オペランドの評価順としては、論理OR演算子が短絡評価であるため、まず左側のオペランド(e % 2 != 0
)が評価されます。この結果は
false
なので、次に右側のオペランド((a == 10 && b == 20)
)を評価します。こちらは論理AND演算子を含んでおり、これも短絡評価なので、先に左側のオペランド(a == 10
)を評価します。これは
true
なので、右側のオペランド(b == 20
)の評価に進み、こちらも
true です。論理AND演算子の両オペランドが true
なので、(a == 10 && b == 20)
は true
です。よって、false || true
が残り、最終的に結果は true
ということになります。
したがって、true になるのは、1、3、4、6です。
std::vector<std::string> の変数から、“Hello” を探すプログラムを作成してください。
これは特定の値(“Hello”)を持った要素を探索するということなので、std::find関数で実現できます(本編解説)。
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::vector<std::string> v {
"Good Morning",
"Hello",
"Good evening",
};
auto it = std::find(std::cbegin(v), std::cend(v), "Hello");
if (it == std::cend(v)) {
std::cout << "not found.\n";
}
else {
std::cout << "found: " << *it << "\n";
}
}
実行結果:
found: Hello
{0, 7, 9, 15, 30, 50} の要素を含んだ std::vector<int> の変数から、値が 30~40 の範囲内にある要素を探すプログラムを作成してください。
これは特定の値ではなく、条件による探索なので、std::find_if関数を使います(本編解説)。
30~40 という範囲を指定するためには、「30以上かつ 40以下」というように条件を読み解く必要があります。これが分かれば、論理AND演算子で接続すればいいと判断できるでしょう。
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v {0, 7, 9, 15, 30, 50};
auto it = std::find_if(std::cbegin(v), std::cend(v), [](int e){ return 30 <= e && e <= 40; });
if (it == std::cend(v)) {
std::cout << "not found.\n";
}
else {
std::cout << "found: " << *it << "\n";
}
}
実行結果:
found: 30
{0, 7, 9, 15, 30, 50} の要素を含んだ std::vector<int> の変数から、100 を割り切ることができる値を持った要素を探すプログラムを作成してください。
こちらも条件による探索なので、std::find_if関数を使います。
100 を割り切ることができるかどうかなので、要素を e
とすると、100 % e == 0
が true
になるものを探せばいいことになります。ここでポイントになるのは、対象の
std::vector の要素に 0
が含まれていることです。e が 0
のとき 100 % e
はゼロ除算になってしまうため、これを回避しなければなりません。
#include <algorithm>
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v {0, 7, 9, 15, 30, 50};
auto it = std::find_if(std::cbegin(v), std::cend(v), [](int e){ return e != 0 && 100 % e == 0; });
if (it == std::cend(v)) {
std::cout << "not found.\n";
}
else {
std::cout << "found: " << *it << "\n";
}
}
実行結果:
found: 50
ゼロ除算を回避するために、論理AND演算子の短絡評価を利用しています。e != 0 && 100 % e == 0
のように、左側のオペランドでゼロでないことを確認しておけば、右側のオペランドが評価されるときには、e
が 0 でないことが確実になります。0
だったときには右側のオペランドは評価されることなく、全体として false
であると判断されます。
std::string の変数から、一番最後にあらわれる .
を見つけるプログラムを作成してください。たとえば、“abc.de.fgh.ij”
という文字列なら、i
の手前にある .
を見つけるようにしてください。
値の探索なので、std::find関数を使います。これまでと異なるのは、一番 “最後” に現れる要素を見つけたいという点です。
これはつまり、逆方向からの探索がしたいということなので、逆イテレータを使って実現します。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>
#include <vector>
int main()
{
std::string s {"abc.de.fgh.ij"};
auto it = std::find(std::rbegin(s), std::rend(s), '.');
if (it == std::rend(s)) {
std::cout << "not found.\n";
}
else {
*it = '*'; // 確認のために書き換える
std::cout << s << "\n";
}
}
実行結果:
abc.de.fgh*ij
見つけた要素が本当に最後の .
かどうか確認するために、得られたイテレータをデリファレンスして、*
に書き換えるようにしました。書き換え後の文字列を出力して確認しています。要素の書き換えのために通常の逆イテレータにしましたが、要素の書き換えが不要であれば、const逆イテレータを使えます。
はてなブックマーク に保存 | Pocket に保存 | Facebook でシェア |
X で ポスト/フォロー | LINE で送る | noteで書く |
RSS | 管理者情報 | プライバシーポリシー |