質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

442閲覧

Atcoder EX16 隣り合う同じ値を探すについて

thxya1

総合スコア3

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2022/06/13 05:48

自分で考えた解答が2種類あるのですが、どちらも不正解となってしまっていて困っています。
どこが間違っているのか教えていただけないでしょうか。
また1つ目の if (data.at(i) == data.at(i+1)の部分の(i+1)をi++にすると、コンパイルエラー(warning: operation on ‘i’ may be undefined)が出ました。i++ではダメなのでしょうか。
よろしくお願いします。

1. #include <bits/stdc++.h> using namespace std; int main() { vector<int> data(5); for (int i = 0; i < 5; i++) { cin >> data.at(i); } for (int i = 0; i < 4; i++) { if (data.at(i) == data.at(i+1)) { cout << "YES" << endl; } else { cout << "NO" << endl; } } }
2. #include <bits/stdc++.h> using namespace std; int main() { vector<int> data(5); for (int x : data) { int i = 0; cin >> data.at(i); if (data.at(i) == data.at(i+1)) { cout << "YES" << endl; } else { cout << "NO" << endl; } } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/06/13 06:05

問題へのリンクを示すなり,問題の内容を述べるなりすべきでは.
fana

2022/06/13 06:20 編集

> どこが間違っているのか とか問うなら,【間違っていないと考える論拠】を示すべき. 「これがこうなんだからこの処理はこのように動くハズで,実際に動かしてみた結果もこうなっているから求められている条件を満たしているハズなのに,一体どこが悪いというのか?」とか何とか堂々と述べよ. それができない状況にあるなら,コードを書く前に「処理順序を筋道立てて考える」ということをすべき. 「i++がどうの」いう話も同様. i+1 と i++ とは全然違う処理であるのに,なぜ「どっちでもOKなハズ」みたいな考えに至るのか?
guest

回答3

0

ベストアンサー

ループを抜けていないからです。

たとえば 1, 2, 4, 4, 6 といったような数列があった場合に

NO NO YES NO

と表示されます。 問題が求めているのは隣り合う値が同じものが (ひとつでも) 存在するするなら YES で、存在しないなら NO というただひとつの答えです。

i++にすると、コンパイルエラー

副作用を持つ演算はそのタイミングについて未規定な部分があります。 i++i が更新されるタイミングが「副作用完了点 (sequence point) までのどこか」であり、この場合は比較が終わったタイミングが副作用完了点です。

つまり data.at(i)i を評価するタイミングですでにインクリメントしているかもしれませんし、していないかもしれません。 コンパイラはどちらと解釈してもかまわないので、逆に言えばプログラマはどちらかの結果になることをあてにしてはなりません。

投稿2022/06/13 06:16

編集2022/06/13 06:17
SaitoAtsushi

総合スコア5446

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thxya1

2022/06/13 07:16

回答していただき、ありがとうございます。おかげさまでなぜ不正解になるのか理解することが出来ました。ありがとうございます。 新たに疑問に思うことがありましたので、よろしければ回答していただけると幸いです。 このEX16の解答例にて「bool値を始めはfalseにしておき、条件を満たすときにtrueになるようにする」と書かれているのですが、なぜ始めからtrueではいけないのでしょうか。始めからtrueで試してみたところ不正解となりました。 よろしくお願いします。
SaitoAtsushi

2022/06/13 08:34

「bool値を始めはfalseにしておき、条件を満たすときにtrueになるようにする」をブール代数にあてはめると各比較結果の論理和をとる演算と考えることができます。 つまり上述の例 1, 2, 4, 4, 6 をあらためて考えると、比較結果はそれぞれ F, F, T, F であり、これに初期値の F を加えて F+F+F+T+F (ここでは真値を T, 偽値を F, 論理和を + で記述しています) とするのと同じ操作だということです。 これの初期値を T にしてみると T+F+F+T+F となり、論理和においては一方が真であれば演算結果は常に真ですから初期値が真であれば結果は常に真であるということになってしまいます。 (偽は単位元 (加法単位元) なので影響を与えない。) 入力に関係なく常に真になるのは当然ながら誤った動作ですね。 初期値を偽にするのではなく最初の値を初期値にして残りを走査するという方法でもいいですよ。
thxya1

2022/06/13 11:04

回答ありがとうございます。 Tを初期値にすると if (data.at(i) == data.at(i + 1)) { ans = true; } の時「(data.at(i) == data.at(i + 1)」ではない時に自動的にFになる訳ではなく、どちらもTになってしまうので間違ってしまう、という理解の仕方で大丈夫でしょうか?
SaitoAtsushi

2022/06/13 11:27

まあそうですね。 真が入っているものが変更される機会がなければ真のままです。
thxya1

2022/06/13 13:03

回答していただいてありがとうございました。 理解することが出来ました。プログラミング初心者なので右も左も分かりませんでしたが、今回簡潔に分かりやすく教えていただいて理解することができ、嬉しくなりました。 ありがとうございました。
guest

0

隣接する同じ要素を見つけるなら std::adjacent_find 使うのが手っ取り早いのでは?

C++

1#include <iostream> 2#include <vector> 3#include <algorithm> 4 5int main() { 6 using namespace std; 7 vector<int> data(5); 8 for (int i = 0; i < 5; i++) { 9 cin >> data.at(i); 10 } 11 if ( adjacent_find(data.begin(), data.end()) != data.end() ) { 12 cout << "YES" << endl; 13 } else { 14 cout << "NO" << endl; 15 } 16 17}

投稿2022/06/13 06:20

編集2022/06/13 06:24
episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

同値が隣り合っている個所があるか否かを Yes/No で出力するのであれば,出力すべき回数は1回である.
ループの中で何度も Yes や No を出力するのは間違いであろう.

コード2. については,ループ方法の記述をなんでそう書くのかイミフだし,i+1 番目の要素が入力されるよりも前に参照されているし,ぐちゃぐちゃ.

投稿2022/06/13 06:09

fana

総合スコア11658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2022/06/13 06:10

どうでもいいが,要素数が5個で固定であれば vector なんて持ち出す必要も無い.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問