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

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

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

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

Q&A

解決済

5回答

1545閲覧

C++で括弧対応検査

waribashi

総合スコア30

C++

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

0グッド

0クリップ

投稿2018/06/17 09:19

編集2018/06/17 10:01

前提・実現したいこと

C++でスタックを使って括弧の対応検査をしたいのですが、入力に対して出力がおかしいです。

キーボードから文字列を入力し、「(),[],{}」の三種類の括弧が対応しているかを検査します。
・開き括弧の数<閉じ括弧の数→開き括弧が不足
・閉じ括弧の数<開き括弧の数→閉じ括弧が不足
・開き括弧と閉じ括弧の対応が取れていない→開き括弧と閉じ括弧が対応していない
・上記三つに当てはまらない場合→括弧の対応が取れている
という旨をそれぞれの場合によって出力したいです。

何回もコードを見直したのですが、自分でどこが間違っているのか分かりません。
どこが間違っているか教えていただけますでしょうか。

###入力と出力
入力:()   出力:開き括弧と閉じ括弧の型が不一致です。
入力:{}   出力:括弧の対応が取れています。
入力:[aaa]  出力:括弧の対応が取れています。
入力:{aaa{ 出力:括弧の対応が取れています。

該当のソースコード

C++

1#include<iostream> 2#include <stack> 3using namespace std; 4 5void main() { 6 stack<char> st; //スタック 7 char left[3] = { '(','[','{' }; //開き 8 char right[3] = { ')',']','}' };//閉じ 9 char in; //入力 10 char R; //ポップした閉じかっこ入れ 11 cout << "カッコ対応検査をする文字列を入力してください。\n"; 12 13 //最初の一文字をとる 14 in = cin.get(); 15 16 while (in != '\n') { 17 for (int i = 0; i < 3; i++) { 18 //inが開きカッコの時 19 if (in == left[i]) { 20 st.push(in); 21 } 22 //inが閉じカッコの時 23 else if (in == right[i]) { 24 //閉じカッコかつスタックが空の時、開きかっこ不足 25 if (st.empty()) { 26 cout << "開き括弧が不足です。\n"; 27 return; 28 } 29 //閉じカッコかつスタックが空じゃないとき 30 else { 31 //Rにポップした閉じカッコを入れる 32 R = st.top(); 33 st.pop(); 34 //inとRが対応しているカッコか調べる 35 for(int j = 0; j < 3; j++) { 36 if (!((R == right[j]) && (in == left[j]))) { 37 cout << "開き括弧と閉じ括弧の型が不一致です。\n"; 38 return; 39 } //if 40 } //for 41 } //else 42 } //else if 43 //inが開きカッコでも閉じカッコでもないとき 44 } 45 //次の一文字を読む 46 in = cin.get(); 47 } 48 //ここまで終わってスタックが空ではないとき、閉じかっこ不足 49 if (!st.empty()) { 50 cout << "閉じ括弧が不足です。\n"; 51 return; 52 } 53 //上記すべてに当てはまらないとき、カッコの対応が取れている 54 cout << "括弧の対応が取れています。\n"; 55 56}

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

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

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

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

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

guest

回答5

0

//inが開きカッコでも閉じカッコでもないとき else { break; }

なんのためにbreakしているのでしょうか?

投稿2018/06/17 09:53

編集2018/06/17 09:53
asm

総合スコア15147

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

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

waribashi

2018/06/17 09:57

あ、すみません。消し忘れていました。何か変わるかなと思ってbreakを入れてたのですが、何も変わらなかったので、ただの消し忘れです。すみません
asm

2018/06/17 10:01

ここでbreakすることで、()の検査だけやったら次の文字に行ってしまい {}[]の対応について検査をしておらず 質問のような状況になっています。
waribashi

2018/06/17 11:03

なるほど、ありがとうございます
guest

0

ベストアンサー

こんにちは。

Rに入るのは閉じ括弧ではなく開き括弧ではないでしょうか?
また、if (!((R == right[j]) && (in == left[j]))のタイミングで既に i には括弧の種別が入っていますので、改めてサーチする必要は無い筈です。スタック上の開き括弧がleft[i]と不一致なら「対応していない」という判定で良いように思います。

投稿2018/06/17 10:17

Chironian

総合スコア23272

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

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

waribashi

2018/06/17 11:02

いけました、ありがとうございます!
guest

0

ちょっと実行してみました。

(123) => 開き括弧と閉じ括弧の型が不一致です。
[123] => 括弧の対応が取れています。
{123} => 括弧の対応が取れています。

下2つは、asmさん指摘の breakのためです。
最初のは、判定ミスのようです。

デバッガのステップ実行で、簡単な例から、調べてみましょう。
最初の

for (int i = 0; i < 3; i++) {

がまず、問題と思います。

if (!((R == right[j]) && (in == left[j]))) {

も比較するものが違っています。

投稿2018/06/17 10:12

pepperleaf

総合スコア6383

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

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

waribashi

2018/06/17 11:05

ありがとうございます、解決いたしました
guest

0

以下のようにすればできました。(少なくとも例の入出力のばあい)

ポイントは

  • 一段目のforがelseのbreakのせいでおかしい挙動している
  • 二段目のforはRとinが同じか?というif文に置換できる(下のプログラムではインデックスで比較している)

の2つでした。

c++

1#include<iostream> 2#include <stack> 3using namespace std; 4 5int main() { 6 stack<char> st; //スタック 7 char left[3] = { '(','[','{' }; //開き 8 char right[3] = { ')',']','}' };//閉じ 9 char in; //入力 10 char R; //ポップした閉じかっこのインデックス入れ 11 cout << "カッコ対応検査をする文字列を入力してください。\n"; 12 13 //最初の一文字をとる 14 in = cin.get(); 15 16 while (in != '\n') { 17 for (int i = 0; i < 3; i++) { 18 //inが開きカッコの時 19 if (in == left[i]) { 20 st.push(i); 21 } 22 //inが閉じカッコの時 23 else if (in == right[i]) { 24 //閉じカッコかつスタックが空の時、開きかっこ不足 25 if (st.empty()) { 26 cout << "開き括弧が不足です。\n"; 27 return 0; 28 } 29 //閉じカッコかつスタックが空じゃないとき 30 else { 31 //Rにポップした閉じカッコを入れる 32 R = st.top(); 33 st.pop(); 34 //inとRが対応しているカッコか調べる 35 if (i != R) { 36 cout << "開き括弧と閉じ括弧の型が不一致です。\n"; 37 return 0; 38 } //if 39 } //else 40 } //else if 41 //inが開きカッコでも閉じカッコでもないとき 42 } 43 //次の一文字を読む 44 in = cin.get(); 45 } 46 //ここまで終わってスタックが空ではないとき、閉じかっこ不足 47 if (!st.empty()) { 48 cout << "閉じ括弧が不足です。\n"; 49 return 0; 50 } 51 //上記すべてに当てはまらないとき、カッコの対応が取れている 52 cout << "括弧の対応が取れています。\n"; 53 54}

投稿2018/06/17 10:07

higumachan

総合スコア19

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

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

waribashi

2018/06/17 11:04

丁寧にありがとうございます、解決いたしました
guest

0

Eclipseかなんか使ってデバッグしましょうよ

投稿2018/06/17 09:38

y_waiwai

総合スコア87719

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

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

waribashi

2018/06/17 10:00

Visual Studioでデバックしてみたのですが、特におかしな点はなかったです。
y_waiwai

2018/06/17 10:05

おかしな点がないのに、どうやっておかしいと判断されてるんでしょうか。 言ってることが矛盾してますぜw
y_waiwai

2018/06/17 10:08

VisualStudioでは、ブレークポイントを設定して、コードの任意の場所で実行を止め、各変数の内容を参照することができます。 また、そこから、変数の内容を参照しながらコードを1行づつ実行するようなこともできます。 そういうのでプログラムの動きを追っていってはどうでしょう
waribashi

2018/06/17 10:12

私がおかしいと思ったのは、入力に対して出力が意図しているものにならない点です。 Visual Studioでデバッグしておかしな点が無かったと言ったのは、先ほど「Hello, world!」を出力するだけのコードをVisual Studioでデバッグしてみたのですが、出力されたメッセージがこのプログラムを出力して出てきたメッセージと、ファイル名等を除いて一致していたためです。 言葉足らずで申し訳ございません。
y_waiwai

2018/06/17 10:19

なら、あなたがおかしいと思うコードを、デバッグしてみましょうよ。。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問