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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

650閲覧

カッコの数を出力する

YuhiKUROIWA

総合スコア9

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/06/22 01:04

編集2020/06/22 01:06

括弧ばかりからなる記号列が正しい形になっているかどうかを調べたい。括弧には、小括弧 ( )、中括弧 { }、大括弧 [ ] がある。それぞれの括弧は、その開き記号と閉じ記号とが対応していなければならない。正確にいうと、括弧ばかりからなる記号列が与えられとき、つぎの操作を可能な限り繰り返すことでその記号列が空となるならば、その記号列は正しいという。
( と ) がこの順に隣り合って並んでいるなら、共に取り除く。
{ と } がこの順に隣り合って並んでいるなら、共に取り除く。
[ と ] がこの順に隣り合って並んでいるなら、共に取り除く。
入力に与えられた括弧ばかりからなる記号列が正しいなら correct と1行に出力し、正しくなければ wrong と1行に出力するプログラムを作れ。
なお出力の末尾には改行を書き出すこと。

入力例1
({()[]}[{()()((()))}])({}[])
出力例1
correct

が問題です。
以前行ったコメントの数を出力するプログラムを参考にしてやってみたのですがコンパイルすらうまくいきません。どうしたらよいですか。教えていただきたいです。コードは以下です。2個目のコードが以前行ったコメント出力のものです。長くなってしまいすみません。

コード#include <stdio.h> typedef enum{ OUT, /*外*/ BRAC1, /*(*/ BRAC2, /*)*/ BRAC3, /*{*/ BRAC4, /*}*/ BRAC5, /*[*/ BRAC6, /*]*/ }state_t; int main(void){ state_t state=OUT; int ch; while((ch=getchar())!=EOF){ switch(state){ case OUT: if(ch=='('){ state=BRAC1; break; case BRAC1: if(ch==')'){ state=BRAC2; }else{ break; } }else if(ch=='{'){ state=BRAC3; break; case BRAC3: if(ch=='}'){ state=BRAC4; }else{ break; } }else if(ch=='['){ state=BRAC5; break; case BRAC3: if(ch==']'){ state=BRAC6; }else{ break; } } } } printf("true"); return 0; } #include <stdio.h> typedef enum { OUT, /* コメントの外 */ SLASH, /* コメントはじめの'/' */ IN, /* コメントの中 */ STAR, /* コメントおわりの'*' */ } state_t; int main(void) { int count = 0; state_t state = OUT; int ch; while ( (ch = getchar()) != EOF ) { switch ( state ) { case OUT: if ( ch == '/' ) state = SLASH; break; case SLASH: if ( ch == '*' ) state = IN; else if ( ch != '/' ) state = OUT; break; case IN: if ( ch == '*' ) state = STAR; break; case STAR: if ( ch == '/' ){state = OUT; count++; }else if ( ch != '*' )state = IN; break; } } printf("%d\n", count); /* 結果の出力 */ return 0; }

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

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

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

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

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

cateye

2020/06/22 01:23

「コメントを取り除く処理」と「カッコを数える」処理をパイプで繋げばいいのでは?
YuhiKUROIWA

2020/06/22 23:56

ありがとうございます。参考にさせていただきます。
guest

回答4

0

元の文字列を壊さないので、文字列リテラルでも大丈夫なコード。

C

1#include <stdio.h> // puts 2#include <string.h> // strchr 3 4const char *s, *pa = "([{", *ren = ")]}"; 5 6int parse(void) 7{ 8 int c; char *p; 9 while ((c = *s++) && (p = strchr(pa, c))) 10 if (parse() != ren[p - pa]) return 1; 11 return c; 12} 13 14int main(void) 15{ 16 s = "({()[][]([{}[]])}[{()()((()))}])({}[])"; 17 puts(parse() ? "wrong" : "correct"); 18}

投稿2020/06/22 02:23

編集2020/06/22 02:45
kazuma-s

総合スコア8224

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

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

YuhiKUROIWA

2020/06/22 23:57

ありがとうございます。参考にさせていただきます。
guest

0

スタックを使う方法

文字列を先頭から見て

  • 左括弧(,{,[が来たらスタックに積む
  • 右括弧が来たら、スタックの先頭と比較して、ペアにできるなら取り出す、ペアにならないなら失敗
  • スタックが最後空になったら成功

C++で実装したけど質問はCだった……Cでスタックが出来んこともないけど……参考まで

c++

1#include <bits/stdc++.h> 2using namespace std; 3 4int main(){ 5 string L = "({["; 6 string S = "({()[][]([{}[]])}[{()()((()))}])({}[])"; 7 stack<char> st; 8 bool flag = true; 9 for(int i=0; i<S.size(); i++){ 10 if(S[i]==L[0] || S[i]==L[1] || S[i]==L[2])st.push(S[i]); 11 if(st.size()==0){flag=false;break;} 12 char t = st.top(); 13 switch(S[i]){ 14 case ')':if(t==L[0])st.pop(); else flag=false; break; 15 case '}':if(t==L[1])st.pop(); else flag=false; break; 16 case ']':if(t==L[2])st.pop(); else flag=false; break; 17 } 18 if(!flag)break; 19 } 20 if(!flag || st.size()>0)cout<<"wrong\n"; 21 else cout<<"correct\n"; 22}

投稿2020/06/23 00:54

編集2020/06/23 01:25
ohys

総合スコア147

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

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

kazuma-s

2020/06/23 01:11

string S = ")"; の場合、wrong になってほしいのに、そうなりません。
ohys

2020/06/23 01:14

コーナーケースの管理が雑でしたね
kazuma-s

2020/06/23 01:24

st.top() の前に st.size() をチェックしないといけないのでは?
ohys

2020/06/23 01:25

コピペミスった…
guest

0

ベストアンサー

fanaさんのを実装してみた:

C

1#define _CRT_SECURE_NO_WARNINGS 2#include <string.h> 3#include <stdio.h> 4#include <stdbool.h> 5 6int main() { 7 char kakko[] = "({()[][]([{}[]])}[{()()((()))}])({}[])"; 8 char* pos; 9 bool removed; 10 do { 11 removed = false; 12 pos = strstr(kakko, "()"); if ( pos ) { strcpy(pos, pos + 2); removed = true; } 13 pos = strstr(kakko, "{}"); if ( pos ) { strcpy(pos, pos + 2); removed = true; } 14 pos = strstr(kakko, "[]"); if ( pos ) { strcpy(pos, pos + 2); removed = true; } 15 puts(kakko); 16 } while ( removed ); 17 if ( strlen(kakko) ==0 ) { 18 puts("全部消えたからcorrect"); 19 } 20}

投稿2020/06/22 01:32

編集2020/06/22 01:34
episteme

総合スコア16614

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

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

YuhiKUROIWA

2020/06/22 23:57

ありがとうございます。参考にさせていただきます。
guest

0

隣り合って並んでいるなら、共に取り除く

というルールしか存在しないようなので,謎のステート管理チックな処理は不要でしょう.
単に
「{"()", "{}", "[]"}のいずれかを見つけたら除去する」という処理を
できなくなるまでやり続けるだけで済む話に思えます.
(できなくなった時点の内容次第で結果を判断すればよい)


まぁ,やり方は上記以外にも有り得るでしょうけども,
現在のコードを活かした方向での話を行うならば,
まずはご自身の考えているやり方(アルゴリズム)の説明が必要であろうと思います.

投稿2020/06/22 01:12

fana

総合スコア11663

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

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

fana

2020/06/22 02:06 編集

まぁ,提示コードから,「入力文字列全体を保持することを避けたいのかな?」とか "推測" はできるのですが.
YuhiKUROIWA

2020/06/22 23:58

ありがとうございます。参考にさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.47%

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

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

質問する

関連した質問