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

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

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

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

Q&A

解決済

5回答

2107閲覧

1桁の正整数と加算、乗算、括弧(入れ子なし)に対応した電卓

culepass_1899

総合スコア2

C

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

0グッド

1クリップ

投稿2021/10/25 17:32

前提・実現したいこと

C言語で電卓を作っています。たとえば1+3*(2+4)のように、一桁の正整数、加算、乗算、括弧(入れ子なし)からなる式が入力された時、計算結果を画面に表示するプログラムを作りたいです。
ここに質問の内容を詳しく書いてください。
入力された式は一旦文字列型の配列に格納し、その後整数型の配列に変換します。この際、後で探索がしやすいように'('は-1,')'は-2,'+'は-3,'*'は-4として変換しています。
ここからが問題で、たとえば上の式であれば、まず(2+4)を計算すると思います。そのように、選択した部分の計算を実行するにはどうしたら良いでしょうか。()や+,といった演算子に応じて範囲を選択し、該当部分の計算を実行するというアルゴリズムでいこうと思っています。
まずは()を探索し、()内の加算、乗算を行います。
→ここで役目を終えた括弧を消去したいのですが、それはどのようにしたら良いでしょうか。
次に加算、乗算についてです。
たとえば
a[i]の演算子が+だった場合、a[i-1]=a[i-1]+a[i+1];
a[i]の演算子が
だった場合、a[i-1]=a[i-1]a[i+1];
とすれば計算結果は得られますが、この後の処理はどうすれば良いでしょうか。
配列を左にどんどん詰めていくというのが基本的な考え方だと思うのですが、ではどのタイミングで詰めるのかがわかりません。
演算子
がなくなるまで乗算を実行、その後演算子+がなくなるまで加算を実行というプロセスでいいことはわかります。
どの処理を関数として定義するかが全くわかりません。
ご回答のほどよろしくお願いいたします。

■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

#include <stdio.h>
int main(void)
{
char formula1[100];
printf("式を入力してください:" );
gets(formula1);//ひとまず文字型の配列に数字等を格納

//型の変換
int formula2[100];//変換後の数値、記号を格納する配列
for (int i = 0; i < 100; i++) {
if(formula1[i]=='('){formula2[i]=-1;}
else
if(formula1[i]==')'){formula2[i]=-2;}
else
if(formula1[i]=='+'){formula2[i]=-3;}
else
if(formula1[i]=='*'){formula2[i]=-4;}
else
{formula2[i]=formula1[i]-'0';}//数字なら数値に変換
}

}
c言語```ここに言語名を入力
ソースコード

### 試したこと ここに問題に対して試したことを記載してください。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。

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

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

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

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

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

y_waiwai

2021/10/25 22:08

このままではコードが読みづらいので、質問を編集し、<code>ボタンを押し、出てくる’’’の枠の中にコードを貼り付けてください
dodox86

2021/10/25 23:29

> ()や+,*といった演算子に応じて範囲を選択し、該当部分の計算を実行するというアルゴリズムでいこうと思っています。 これはまだアルゴリズムと言えるほどのものではなく、いわば「方針」です。まず、カッコは考えず入力された文字列の左端から順番に四則演算だけでもできるでしょうか。それだけでも恐らく初心の方には難しいものですし、それがまだできない場合、カッコを考えた優先順位付きの計算は無理だと思います。現状ですと、分からないことがほとんどのようでほぼ丸投げの印象を受けます。
jimbe

2021/10/26 18:11 編集

少なくとも括弧の無い足し算だけ掛け算だけの式は計算出来て、括弧を付けての式をそれなりの内部構造に変換して壁に当たった…程度までは頑張って欲しいものですが。
guest

回答5

0

ベストアンサー

正規表現を使えばこうなるでしょう。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <regex.h> 5 6regex_t preg[3]; 7 8void replace(char *f, int so, int eo, int v) { 9 sprintf(&f[so], "%d", v); 10 strcat(f, &f[eo]); 11} 12 13int calc(char *f) { 14 regmatch_t match[3]; 15 // () 16 while(!regexec(&preg[0], f, 1, match, 0)) { 17 f[(int)match[0].rm_eo-1] = '\0'; 18 int v = calc(&f[match[0].rm_so+1]); 19 replace(f, match[0].rm_so, match[0].rm_eo, v); 20 } 21 // * 22 while(!regexec(&preg[1], f, 3, match, 0)) { 23 int v1 = (int)strtol(&f[match[1].rm_so], NULL, 10); 24 int v2 = (int)strtol(&f[match[2].rm_so], NULL, 10); 25 int v = v1 * v2; 26 replace(f, match[0].rm_so, match[0].rm_eo, v); 27 } 28 // + 29 while(!regexec(&preg[2], f, 3, match, 0)) { 30 int v1 = (int)strtol(&f[match[1].rm_so], NULL, 10); 31 int v2 = (int)strtol(&f[match[2].rm_so], NULL, 10); 32 int v = v1 + v2; 33 replace(f, match[0].rm_so, match[0].rm_eo, v); 34 } 35 return atoi(f); 36} 37 38void test(char *formula) { 39 printf("f=%s\n", formula); 40 41 regcomp(&preg[0], "\([^(]+\)", REG_EXTENDED|REG_NEWLINE); // () 42 regcomp(&preg[1], "([0-9]+)\*([0-9]+)", REG_EXTENDED|REG_NEWLINE); // * 43 regcomp(&preg[2], "([0-9]+)\+([0-9]+)", REG_EXTENDED|REG_NEWLINE); // + 44 45 char *f = malloc(strlen(formula)+1); 46 strcpy(f, formula); 47 48 int a = calc(f); 49 printf("a=%d\n", a); 50 51 free(f); 52 53 regfree(&preg[2]); 54 regfree(&preg[1]); 55 regfree(&preg[0]); 56} 57 58int main(int argc, char *argv[]) { 59 test("1+2"); 60 test("2*3"); 61 test("1+2*3"); 62 test("(1+2)*3"); 63 test("1+3*(2+4)"); 64}

plain

1f=1+2 2a=3 3f=2*3 4a=6 5f=1+2*3 6a=7 7f=(1+2)*3 8a=9 9f=1+3*(2+4) 10a=19

参考までに、スタックでベタに逆ポーランド記法利用時はこんな感じかと。

c

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <ctype.h> 5#include <limits.h> 6 7/* 8 * スタック 9 */ 10 11#define STACK_MAX 100 12int istack[STACK_MAX]; 13char *cstack[STACK_MAX]; 14int sp; 15 16void cpush(char *token) { 17 cstack[sp++] = token; 18} 19 20char *cpop() { 21 return sp > 0 ? cstack[--sp] : NULL; 22} 23 24char *cpeek() { 25 return sp > 0 ? cstack[sp-1] : NULL; 26} 27 28void ipush(int value) { 29 istack[sp++] = value; 30} 31 32int ipop() { 33 return sp > 0 ? istack[--sp] : INT_MAX; 34} 35 36/* 37 * 式分解(一文字ずつ文字列化) 38 */ 39 40#define BUFFER_MAX 1024 41char buf[BUFFER_MAX]; 42 43char **splitFormula(char *formula) { 44 memset(buf, 0, sizeof(buf)); 45 char **tokens = malloc((strlen(formula)+1)*sizeof(char*)); 46 char *p = buf; 47 for(int i=0; i<strlen(formula); i++) { 48 *p = formula[i]; 49 tokens[i] = p; 50 p += 2; 51 } 52 tokens[strlen(formula)] = NULL; 53 return tokens; 54} 55 56/* 57 * RPN化 58 */ 59 60int priority(char *op) { 61 if(*op == '*') return 1; 62 if(*op == '+') return 0; 63 return -1; 64} 65 66void toRPN(char *tokens[]) { 67 sp = 0; 68 int j = 0; 69 for(int i=0; tokens[i]!=NULL; i++) { 70 char *token = tokens[i]; 71 if(isdigit((int)*token)) { 72 tokens[j++] = token; 73 } else if(*token == '(') { 74 cpush(token); 75 } else if(*token == ')') { 76 for (char *t; (t=cpop())!=NULL && *t!='('; ) tokens[j++] = t; 77 } else { 78 while(cpeek()!=NULL && priority(cpeek()) >= priority(token)) tokens[j++] = cpop(); 79 cpush(token); 80 } 81 } 82 for (char *t; (t=cpop())!=NULL; ) tokens[j++] = t; 83 tokens[j] = NULL; 84} 85 86/* 87 * 計算 88 */ 89 90int calc(char *rpn[]) { 91 sp = 0; 92 for(int i=0; rpn[i]!=NULL; i++) { 93 if(isdigit((int)*rpn[i])) { 94 ipush(atoi(rpn[i])); 95 } else { 96 int v2 = ipop(); 97 int v1 = ipop(); 98 if(*rpn[i] == '*') { 99 ipush(v1 * v2); 100 } else if(*rpn[i] == '+') { 101 ipush(v1 + v2); 102 } 103 } 104 } 105 return ipop(); 106} 107 108/* 109 * 確認用 110 */ 111 112void printTokens(char *tokens[]) { 113 for(int i=0; tokens[i]!=NULL; i++) printf(" %s", tokens[i]); 114 printf("\n"); 115} 116 117void test(char *formula) { 118 char **expr = splitFormula(formula); 119 printTokens(expr); 120 toRPN(expr); 121 printTokens(expr); 122 printf("%d\n", calc(expr)); 123 free(expr); 124} 125 126int main(int argc, char *argv[]) { 127 test("1+2"); 128 test("2*3"); 129 test("1+2*3"); 130 test("(1+2)*3"); 131 test("1+3*(2+4)"); 132}

plain

1 1 + 2 2 1 2 + 33 4 2 * 3 5 2 3 * 66 7 1 + 2 * 3 8 1 2 3 * + 97 10 ( 1 + 2 ) * 3 11 1 2 + 3 * 129 13 1 + 3 * ( 2 + 4 ) 14 1 3 2 4 + * + 1519

投稿2021/10/26 13:26

編集2021/10/27 10:56
jimbe

総合スコア12756

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

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

0

いろいろなやり方があります。たとえば、これはどうでしょうか?

C

1#include <stdio.h> // fgets, printf 2 3char a[1000]; 4int i, c, expr(void); 5 6int factor(void) 7{ 8 int v = 0; 9 c = a[i++]; 10 if (c == '(') { 11 v = expr(); 12 if (c == ')') c = a[i++]; 13 else c = 1; 14 } 15 else if (c >= '0' && c <= '9') { 16 v = c - '0'; 17 c = a[i++]; 18 } 19 else c = 1; 20 return v; 21} 22 23int term(void) 24{ 25 int v = factor(); 26 while (c == '*') v *= factor(); 27 return v; 28} 29 30int expr(void) 31{ 32 int v = term(); 33 while (c == '+') v += term(); 34 return v; 35} 36 37int main(void) 38{ 39 fgets(a, sizeof a, stdin); 40 int v = expr(); 41 if (c == '\n' || c == 0) printf("%d\n", v); 42 else puts("error"); 43}

ポインタも構造体もないから、むずかしくないと思うんですが、どうでしょうか?

追記
逆ポーランド記法に変換してから計算するやり方です。

C

1#include <stdio.h> // puts, printf 2 3const char *a; char b[1000]; int i, j, c; void expr(void); 4 5void factor(void) 6{ 7 c = a[i++]; 8 if (c == '(') expr(), c = c == ')' ? a[i++] : 1; 9 else if (c - '0' <= 9u) b[j++] = c, c = a[i++]; 10 else c = 1; 11} 12 13void term(void) { for (factor(); c == '*'; b[j++] = '*') factor(); } 14 15void expr(void) { for (term(); c == '+'; b[j++] = '+') term(); } 16 17int calc(void) 18{ 19 int s[100], p = 0; // s: stack, p: stack pointer 20 for (int k = 0; k < j; k++) 21 if (b[k] == '+') p--, s[p-1] += s[p]; 22 else if (b[k] == '*') p--, s[p-1] *= s[p]; 23 else s[p++] = b[k] - '0'; 24 return s[0]; 25} 26 27void test(const char *s) 28{ 29 puts(a = s); 30 i = j = 0; 31 expr(); 32 if (c) puts(" error"); 33 else { 34 for (int k = 0; k < j; k++) printf(" %c", b[k]); 35 printf(" : %d\n", calc()); 36 } 37} 38 39int main(void) 40{ 41 test("1+2"); 42 test("2*3"); 43 test("1+2*3"); 44 test("(1+2)*3"); 45 test("1+3*(2+4)"); 46}

投稿2021/10/26 08:05

編集2021/10/27 10:35
kazuma-s

総合スコア8224

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

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

0

()や+,*といった演算子に応じて範囲を選択し、該当部分の計算を実行する

という話を,「計算を実行する範囲を2つのポインタで示す」という形でやってみました.

話を簡単にするため,メモリを動的に確保とかはせず,作業用のバッファは「十分なサイズだけ」ローカル変数で用意する形にしてあります.
また,

一桁の正整数、加算、乗算、括弧(入れ子なし)

という条件であることを前提とし,エラーチェックはまともに入ってません.

C

1//文字列の一部.範囲 [begin, end) として表す 2typedef struct SubStr 3{ 4 const char *begin; //先頭の文字を指す 5 const char *end; //末尾の文字の次を指す 6} SubStr; 7 8//(プロトタイプ宣言) 9int EvalStr( const char *begin, const char *end ); 10 11//[begin, end) の範囲から c を探してその場所を返す. 12//見つからない場合は end を返す. 13const char *find( char c, const char *begin, const char *end ) 14{ 15 const char *p = begin; 16 for( ; (p!=end) && ((*p)!=c); ++p ){} 17 return p; 18} 19 20//文字列 [begin, end) をバラす. 21//ただし,括弧で囲まれた範囲の内側まではバラさらない. 22//結果は pBuff の先頭側から突っ込まれる.(pBuff は十分なサイズの領域を指すこと) 23//突っ込んだ個数を返す. 24int ParseToSubStrs( SubStr *pBuff, const char *begin, const char *end ) 25{ 26 int n = 0; 27 const char *p = begin; 28 while( p != end ) 29 { 30 if ( *p == '(' ) 31 {// '(' と ')' で囲まれた範囲(括弧の内側)を1つの結果とする 32 const char *pRightParenthese = find( ')', p+1, end ); 33 if( pRightParenthese == end ) 34 { 35 printf( "Error : Left_parenthese without Right_parenthese" ); 36 exit(0); 37 } 38 pBuff[n].begin = p+1; 39 pBuff[n].end = pRightParenthese; 40 p = pRightParenthese + 1; 41 } 42 else 43 {//※ここに来るとき,pが指すのは,数字(一桁限定なので1文字)か演算子(1文字)であるハズ 44 pBuff[n].begin = p; 45 pBuff[n].end = p+1; 46 ++p; 47 } 48 ++n; 49 } 50 return n; 51} 52 53//単一の SubStr の内容を整数値に解釈する. 54int EvalSubStr_to_Int( SubStr SS ) 55{ 56 if( SS.end - SS.begin > 1 ) 57 { return EvalStr( SS.begin, SS.end ); } 58 else 59 { return *SS.begin - '0'; } //※1桁の数値であることを決め打ちで処理 60} 61 62// nSS 個の連続した SubStr 群を整数値に解釈する. 63int EvalSubStrs( SubStr *pSSs, int nSS ) 64{ 65 if( nSS == 1 ) 66 { return EvalSubStr_to_Int( pSSs[0] ); } 67 68 for( int i=1; i<nSS-1; ++i ) 69 { 70 if( *pSSs[i].begin == '+' ) 71 { 72 int Left = EvalSubStrs( pSSs, i ); 73 int Right = EvalSubStrs( pSSs+(i+1), nSS-(i+1) ); 74 return Left + Right; 75 } 76 } 77 78 for( int i=1; i<nSS-1; ++i ) 79 { 80 if( *pSSs[i].begin == '*' ) 81 { 82 int Left = EvalSubStrs( pSSs, i ); 83 int Right = EvalSubStrs( pSSs+(i+1), nSS-(i+1) ); 84 return Left * Right; 85 } 86 } 87 printf( "Error\n" ); 88 exit( 0 ); 89} 90 91//数式文字列 [begin, end) の内容を評価して結果値を返す. 92int EvalStr( const char *begin, const char *end ) 93{ 94 SubStr SubStrs[16]; //※サイズはてきとー 95 int nSubStr = ParseToSubStrs( SubStrs, begin, end ); //文字列をバラして… 96 return EvalSubStrs( SubStrs, nSubStr ); //評価する 97} 98 99//--------------- 100 101//式1個分をやってみるテスト 102void Test( const char *Str ) 103{ 104 int n = (int)strlen( Str ); 105 printf( "%s = %d\n", Str, EvalStr( Str, Str+n ) ); 106} 107 108int main(void) 109{//いろんな式でテスト 110 Test( "1+3*(2+4)" ); 111 Test( "(3+9)*(2*4)" ); 112 Test( "4+7*2" ); 113 Test( "4*1*5+2" ); 114 return 0; 115}

投稿2021/10/26 07:33

編集2021/10/26 07:46
fana

総合スコア11708

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

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

0

まず、プログラミングは「こう書けばいい」というものではありません。
現実世界のシミュレーションです。

(おそらく質問者さんはお気づきかもしれませんが)

なので、現実世界でならどうするかを考えるのです。
今回の場合、割と楽な気がします。

かっこが使われていますが、入れ子はなく、かつ数字は常に一桁であることが前提のようですから。

F = 1+3*(2+4)

とします。

このFを計算する場合、現実世界ではどのようにしますか?

私なら、『かっこから先に計算』します。

1+3*(2+4) = 1+3*6

ということは、『(…)で囲まれている式を先に計算』するということです。

構造をよくみてください。必ず、“(”と“)”の数は同じであるはずです。そして、入れ子ではない。

ということは、

1. 先頭から末尾までの中で最初の“(“を探す 2. “(”があったら 2.1. “)”の場所を探す 2.2. (1)の場所から(2.1)の場所まで切り出す 2.3. 計算する 2.4. 置き換える

のような感じになるかと思います。

…発想そのものはここまでできているようですね。

あとは実現方法。

現実世界で考えてみてください。質問者さんは脳内ではどのようにやっていますか?
おそらく、かっこの中を先に計算して、そこをYとかのような別の値に変換しているのではないかなと。

F = 1+3*(2+4) 一番優先順位の高い計算はかっこ付きなので”(“を探す。それで囲まれている部分を探す。 (2+4)の計算結果をYと置くと、 F = 1+3*Y と置き換える。 これ以上かっこ付きはないので次の演算子へ。次に優先順位の高いものは掛け算なので、 *を探す。そうすると3*Yがヒット。これを計算する。 この計算結果をXと置くと、 F = 1+X となる。これ以上優先するものはないので以降は先端から計算していく。

的な感じになっているはずです。

もちろん、実際に使う文字や式とかは違いますが。

Yとかを使わずに数字にするのが普通かもしれませんが。

とにかく、『元の計算式の特定の部分を書き換える』的な処理を脳内でしているはずです。
上記で言えば(2+4) を Y とおく感じの。実際にはYではなく、2+4の結果、6と置き換える感じです。

アルゴリズムっぽく考えると、

1. “(”の場所を調べる(int beginとする) 2. “)”の場所を調べる(int endとする) 3. beginからendまでの文字列を切り出す 4. (3)を計算(int tempとする) 5. 元の文字列のbeginからendまでを(4)の値に置き換える これを優先順位が高いものがなくなるまで繰り返す

的な感じになるかなと。

つまり、『切り出し』→『計算』→『元の文字列に置き換え』的な処理ですね。入れ子になっていると面倒ですが、それでも発想は同じかも。


[追記0]

あと、質問では“+”とかを-1やらなんやらに置き換えていますが、それはしなくてもできるはずです。

式全体をFとしたとき、Fは単なる文字列です。
文字列は文字が0文字以上連なったものです。
だから配列で表現するのです。

“1”も“+”も文字です。

それに、出てくる数字に関しては(かっこ内でないなら)常に一桁ですよね。

ということは、

<数字><演算子><数字><演算子>…

となっているはずです。

よくみると、数字と演算子が交互に出ています。となると、かっこ内をすでに計算した後という前提であれば、

1. 文字数分ループ 1.1. 現在の文字を取得 1.2. 現在の文字が“+”なら 1.2.1. 前後の文字をそれぞれ整数にして 1.2.2. 計算する 1.3. (そうじゃなくて) “-”なら …

のような感じになるかなと。

ただし、”1”と 1は別物です。なので『文字を整数にする処理』が必要になります。文字列ではありません。

これに関しては調べてください。

上で切り出したかっこ内の式もこの考えを適用できます。

ーーーー
[追記0:オフトピ]

修正依頼のところに書くべき内容ですが、質問者さんは無視しているのか、やり方がわからないのかわかりませんが、改善されていないようなので書いておきます。

コードは”<code>”または”<コード>”のボタンを押して出てくるやつの中にかきましょう。
ご自分の質問にあるコードと回答者のコード等を比較してみましょう。今のままでは非常に読みづらいです。ひらがなでしかも句読点なしの文章を読まされるようなものです。

知っていて我を押し通すつもりなら次からは回答者が一気に減ると思います。そうすると質問者さんにとって有用な情報も得られなくなります。

知らなかったのなら、これを機にやってみましょう。質問は修正できるので修正してください。

[私が「修正依頼を無視している」と考えた根拠]

過去質問(一件ですが)では、ある方がご指摘なさっていますが、それを無視しています。
もしかしたらMarkdownとかの存在がわからない可能性もあるとは思いますが、流石にアニメーションで提示されているのでそれは無いかなと。

仮に「質問を編集できるということが分かっていなかった」だけだとしても、二回目以降の質問でも同じようなことをやっています。なので「改善する気が無い」人なのかなと勘繰ってみたり。

※このオフトピ追記は質問が修正され次第、削除する予定です。

投稿2021/10/25 22:30

編集2021/10/26 08:14
BeatStar

総合スコア4958

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

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

dodox86

2021/10/26 00:56

> [追記0:オフトピ] > 修正依頼のところに書くべき内容ですが、質問者さんは無視しているのか、やり方がわからないのかわかりませんが、改善されていないようなので書いておきます。 質問の投稿が[2021/10/26 02:32]で、「質問への追記・修正、ベストアンサー選択の依頼」欄においてマークダウンを使用して見易くしましょうとの指摘が[2021/10/26 07:08]です。無視を疑うにはさすがに急ぎ過ぎなのではないでしょうか。 (なお、ご回答への低評価は私がしたものではありません)
K_3578

2021/10/26 01:06

横からですが >さすがに急ぎ過ぎなのではないでしょうか。 https://teratail.com/questions/362341 での追記修正依頼でのやり取りを見る限りでは意図的に無視しているかそもそもMarkdownを理解していないのかと思ったのでこの指摘は質問者に気づいて貰うためにも必要だと私は思います
fana

2021/10/26 01:13

> 必ず、”(“と”(“の数は同じであるはずです。 誤記っす.一方は ')' ですね. あと,私も割と空行を多用しちゃう方だけど,そんな私から見てもちょっと空行が多いなぁと感じます. 段落というか話の切れ目ではない箇所に空行が入るとちょっと読み難いですね. (やたらスクロールしないと読めないのも面倒な感じになりますし)
dodox86

2021/10/26 01:25

@K_3578さん コメントありがとうございます。ご案内の過去質問を見ると確かにそうですね。単独で本質問を読むと早過ぎる印象は解消しませんが、あらゆる指摘をスルーして自分の要望を優先する方もまれによくいらっしゃるから、妥当とも取れます。理解しました。
K_3578

2021/10/26 01:28

@dodox86さん 私もdodox86さんのコメントを見た時は同じ事を思いましたし、BeatStarさんがそこまで意図を汲んで 回答したかはわからないのでご指摘自体は真っ当だと思います。
dodox86

2021/10/26 02:21 編集

@BeatStarさん > まだ完璧に頭が回っているわけじゃないので詳しくはわかりませんが。 えと、この文は必要でしょうか。なぜ、ご自身も認めるあやふやな状態で回答をされるのか。時に、質問内容があやふやだと回答もそうならざるを得ないこともあり、それを踏まえての文だったのかもしれませんが。
BeatStar

2021/10/26 02:29

@ dodox86さん > 無視を疑うにはさすがに急ぎ過ぎなのではないでしょうか この質問だけなら私もそう思いますが、質問者さんの過去質問をみていると、他の方がgifファイルで修正依頼のところに載せていますが、修正された様子もなく、かと言って今回の質問に反映されているわけでもないです。 なので書きました。 とある別のユーザはそういう指摘に対して暴言を吐き、『推奨なのだからやらんくてもいいだろ。答えだけ寄越せ』的発言を繰り返している人も見かけたりします。 そういう手合いなのかなとも勘繰ったり。
BeatStar

2021/10/26 02:31

@ K_3578さん > ... この指摘は質問者に気づいて貰うためにも必要だと私は思います まさにその意図です。
dodox86

2021/10/26 02:32

@BeatStarさん コメントありがとうございます。お気持ちは理解できます。承知しました。
BeatStar

2021/10/26 02:32

@ fanaさん > 誤記っす.一方は ')' ですね. あ、本当ですね。(気づかなかった…) 修正します。
guest

0

演算子の優先順位やカッコに対応した電卓はスタックを使って実装するとやりやすいと思います。
その際、計算対象の数式を逆ポーランド記法という書き方に変換することで演算子の優先順位などの煩わしさを軽減できます。

以下の記事はコードがPerlで書かれているものの、電卓のアルゴリズムについてわかりやすく解説されていますので、よければご一読ください。

日曜プログラミングで電卓を作ってみる | さくらのナレッジ

ご質問いただいたアルゴリズムが複雑でその方法で実装できるか自信がないため、質問に対する直接の回答ができず申し訳ありませんが、ご参考まで。

投稿2021/10/25 21:05

fj68

総合スコア752

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

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

fj68

2021/10/25 21:11

ご質問のアルゴリズムで実装できないか手元で試してみて、回答できるようになったら追記しますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問