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

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

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

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

1090閲覧

【PHP】 配列から取得した値を左から順番に計算して、式の左側の計算結果に右側の計算を行うプログラムを作りたい。

ra-men_love

総合スコア6

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2021/05/05 01:18

前提・実現したいこと

現在、ターミナル上で実行できる計算プログラムの作成をしています。
しかし、1個の演算子を使った計算プログラムはうまくいったのですが、2個以上の演算子が含まれている複合算の計算結果がうまくいきません。

複合算で、左から順番に計算していき(+,-,*,/の四則演算)、左側の計算結果に順次右側の計算を追加?するプログラムを作成したいと考えています。


入力:2+3*4=
結果:20

入力:4+7*2-4/6=
結果:3

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

現在のコードでは、演算子前後の計算をそれぞれ行うため2個以上の演算子が含まれた場合、計算結果がうまく表示されません。


入力:2+3+4=
結果:57

入力:2+5*3=
結果:715

該当のソースコード

$z配列にはユーザーが入力した値を追加しています。
$z = array('2','+','6','*','4','=');
のように、'数字','演算子','数字'の順番になっています。

PHP

1foreach($z as $key=> $j){ 2 if($key % 2 == 1){ 3 switch($j){ 4 case '+'; 5 $num1 = $z[$key - 1]; 6 $num2 = $z[$key + 1]; 7 $num3 = $num1 + $num2; 8 echo $num3; 9 break; 10 11 case '-'; 12 $subtraction1 = $z[$key - 1]; 13 $subtraction2 = $z[$key + 1]; 14 $subtraction3 = $subtraction1 - $subtraction2; 15 echo $subtraction3; 16 break; 17 18 case '*'; 19 $multiplication1 = $z[$key - 1]; 20 $multiplication2 = $z[$key + 1]; 21 $multiplication3 = $multiplication1 * $multiplication2; 22 echo $multiplication3; 23 break; 24 25 case '/'; 26 $division1 = $z[$key - 1]; 27 $division2 = $z[$key + 1]; 28 $division3 = $division1 / $division2; 29 echo $division3; 30 break; 31 32 } 33 34 } 35 36 }

試したこと

①最初の計算結果を配列に追加して、そこに右側の計算を順次追加していく
思いついたのはいいのですが、このようなプログラムが完成できませんでした。

②繰り返し分を使う
foreachの中に繰り返し構文を使ったことで計算結果もうまくいかず、エラーが出る場合もありました。

これ以上の処方が思いつかず、行き詰ってしまいました。

よろしければ、ご教授頂ければ幸いです。

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

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

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

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

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

guest

回答3

0

php

1<?php 2/* 3複合算で、左から順番に計算していき(+,-,*,/の四則演算)、左側の計算結果に順次右側の計算を追加?するプログラムを作成したいと考えています。 4 56入力:2+3*4= 7結果:20 8 9入力:4+7*2-4/6= 10結果:3 11*/ 12$z = ['2','+','6','*','4','=']; 13foreach($z as $key=> $j){ 14 if($key % 2 == 1){ 15 switch($j){ 16 case '+'; 17 $num1 = $z[$key - 1]; 18 $num2 = $z[$key + 1]; 19 $num3 = $num1 + $num2; 20 echo $num3; 21 break; 22 case '-'; 23 $subtraction1 = $z[$key - 1]; 24 $subtraction2 = $z[$key + 1]; 25 $subtraction3 = $subtraction1 - $subtraction2; 26 echo $subtraction3; 27 break; 28 case '*'; 29 $multiplication1 = $z[$key - 1]; 30 $multiplication2 = $z[$key + 1]; 31 $multiplication3 = $multiplication1 * $multiplication2; 32 echo $multiplication3; 33 break; 34 case '/'; 35 $division1 = $z[$key - 1]; 36 $division2 = $z[$key + 1]; 37 $division3 = $division1 / $division2; 38 echo $division3; 39 break; 40 } 41 } 42} 43/* 44①最初(1-a)の計算結果を配列(1-b)に追加して(1-c)、そこに右側の計算を順次追加していく(1-d) 45思いついたのはいいのですが、このようなプログラムが完成できませんでした。 46*/ 47// 1. 48echo PHP_EOL; 49$z = ['2','+','6','*','4','=']; 50$firstDone = false; //1-a 51$ans = []; // 1-b 52foreach($z as $key=> $j){ 53 if($key % 2 === 1){ 54 switch($j){ 55 case '+'; 56 $num1 = $z[$key - 1]; 57 $num1 = $firstDone ? $ans[count($ans) - 1] : $z[$key - 1]; 58 if(!$firstDone) $firstDone = true; 59 $num2 = $z[$key + 1]; 60 $num3 = $num1 + $num2; 61 echo $num3; 62 echo PHP_EOL; 63 $ans[] = $num3; // 1-c, 1-d 64 break; 65 case '-'; 66 $subtraction1 = $z[$key - 1]; 67 $subtraction1 = $firstDone ? $ans[count($ans) - 1] : $z[$key - 1]; 68 if(!$firstDone) $firstDone = true; 69 $subtraction2 = $z[$key + 1]; 70 $subtraction3 = $subtraction1 - $subtraction2; 71 echo $subtraction3; 72 echo PHP_EOL; 73 $ans[] = $subtraction3; // 1-c, 1-d 74 break; 75 case '*'; 76 $multiplication1 = $z[$key - 1]; 77 $multiplication1 = $firstDone ? $ans[count($ans) - 1] : $z[$key - 1]; 78 if(!$firstDone) $firstDone = true; 79 $multiplication2 = $z[$key + 1]; 80 $multiplication3 = $multiplication1 * $multiplication2; 81 echo $multiplication3; 82 echo PHP_EOL; 83 $ans[] = $multiplication3; // 1-c, 1-d 84 break; 85 case '/'; 86 $division1 = $z[$key - 1]; 87 $division1 = $firstDone ? $ans[count($ans) - 1] : $z[$key - 1]; 88 if(!$firstDone) $firstDone = true; 89 $division2 = $z[$key + 1]; 90 $division3 = $division1 / $division2; 91 echo $division3; 92 echo PHP_EOL; 93 $ans[] = $division3; // 1-c, 1-d 94 break; 95 } 96 } 97} 98var_dump($ans); 99/* 100②繰り返し分を使う 101foreachの中に繰り返し構文を使ったことで計算結果もうまくいかず、エラーが出る場合もありました。 102https://www.google.com/search?client=firefox-b-d&q=%E7%B9%B0%E3%82%8A%E8%BF%94%E3%81%97%E6%96%87+php 103-> for や while を使うという意図と推測したものの私の力では foreach のなかで繰り返しを使う方法が分かりませんでした。 104*/ 105// 2. 106$z = ['2','+','6','*','4','=']; 107$ans = $z[0]; 108$key = 1; 109$len = count($z); 110while($len > $key) { 111 if($key % 2 === 1){ 112 switch($z[$key]){ 113 case '+'; 114 $ans += $z[$key + 1]; 115 break; 116 case '-'; 117 $ans -= $z[$key + 1]; 118 break; 119 case '*'; 120 $ans *= $z[$key + 1]; 121 break; 122 case '/'; 123 $ans /= $z[$key + 1]; 124 break; 125 } 126 } 127 $key++; 128} 129echo $ans; 130echo PHP_EOL; 131// 任意の位置にアクセスしない 132$z = ['2','+','6','*','4','=']; 133$ans = INF; 134$add = function($a,$b) {return $a+$b;}; 135$sub = function($a,$b) {return $a-$b;}; 136$mul = function($a,$b) {return $a*$b;}; 137$div = function($a,$b) {return $a/$b;}; 138foreach($z as $char) { 139 switch($char){ 140 case '+'; 141 $ope = $add; 142 break; 143 case '-'; 144 $ope = $sub; 145 break; 146 case '*'; 147 $ope = $mul; 148 break; 149 case '/'; 150 $ope = $div; 151 break; 152 case '=': 153 break; 154 default: 155 $ans = is_infinite($ans) ? intval($char) : $ope($ans, intval($char)); 156 } 157} 158echo $ans;

投稿2021/05/05 18:01

papinianus

総合スコア12705

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

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

0

いわゆる普通の電卓のエミュレーションですかね?
右手に封印した eval が疼いたので、30分一本勝負でコード書いてみましたw
なお、右手せいで質問にあるコードは見てません^^;

php

1<?php 2$inputs = [ 3 '2+3*4=', 4 '4+7*2-4/6=', 5 '22+3*4=', 6 '2+203*4=', 7 '2++23*4=', 8 '2+ 23*4=', 9 '+23*4=', 10 '-23*4=', 11 '*23*4=', 12 '4+7*2-4/6+=',//これだけメッセージ未決定w 13 ]; 14$sum = ''; 15$num = ' '; 16$ope = ""; 17 18foreach($inputs as $input){ 19 $sum = ''; 20 $num = ' '; 21 $ope = ""; 22 $len = mb_strlen($input); 23 for($i = 0; $i < $len - 1; ++$i){ 24 $count = $i; 25 if(in_array($input[$i], ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'])){ 26 $num .= $input[$i]; 27 continue; 28 } 29 if(in_array($input[$i], ['+', '-', '*', '/'])){ 30 if($i === 0 && ($input[0] === '*' || $input[0] === '/')){ 31 echo $input . 'は演算子から始まっている' . PHP_EOL; 32 break; 33 } 34 if($num === ''){ 35 echo $input . 'は演算子が重複してる' . PHP_EOL; 36 break; 37 } 38 $sum = eval('return ' . $sum . $ope . $num .';'); 39 $num = ''; 40 $ope = $input[$i]; 41 $count = 0; 42 continue; 43 } 44 echo $input . 'は式がなんか間違ってる' . PHP_EOL; 45 $count = 0; 46 break; 47 } 48 if($input[$count + 1] === '='){ 49 $sum = eval('return ' . $sum . $ope . $num .';'); 50 echo $input . $sum . PHP_EOL; 51 } 52}
2+3*4=20 4+7*2-4/6=3 22+3*4=100 2+203*4=820 2++23*4=は演算子が重複してる 2+ 23*4=は式がなんか間違ってる +23*4=92 -23*4=-92 *23*4=は演算子から始まっている

なお、eval 使う必要性はホントはありません。あと未完ですw

投稿2021/05/06 03:30

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2021/05/07 03:40

焦った証がいろいろ残ってるなぁ。。。 `+=`とか`==`とかがちゃんと拾えてないですね^^;
guest

0

ベストアンサー

アルゴリズムに行き詰っているのですね。
私からの提案ですが、$z[$key - 1]$z[$key + 1]など任意の場所のデータに自由にアクセスすることは、ここはいったん忘れましょう。
そして、$z = array('2','+','6','*','4','=');のようになっているとして、
foreach ($z as $v) {でループして、
$vを調べて、
・数字だったとき
・'+'や'*'のとき
・'='のとき
に何をするといいか、それぞれ独立・別個に考えましょう。
電卓の中で行われているであろうことを想像してみましょう。
とりあえず以上アドバイスです。

投稿2021/05/05 02:29

itagagaki

総合スコア8402

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

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

ra-men_love

2021/05/05 02:48

任意の場所のデータへのアクセスをせずに、数字の判別や演算子の判別は可能なのでしょうか?
itagagaki

2021/05/05 02:55

ご質問の意味がちょっとよくわからないですが、 $vが数字かどうかは`is_numeric`で判断できますね。 演算子かどうかは、一番手っ取り早いのは if ($v == '+') とか、あなたがすでにやられているように switch ($v) { case '+': } とかで判別できますよね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問