![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?e8efa67b6d)
C言語で、一桁の整数4つをキーボードから入力し、四則演算により答えが10になる全ての式を出力するプログラムを作成するというものです。
条件として、
・演算子には優先順位があるものとする
・同じ演算子は使用不可
・カッコを用いた計算方法は考えない
→例 (1+2)*4=12など
・int型の変数のみ使用可
です。
以下の様に、全パターンをひとつづつ試行して、10になるかどうか判定するというような力技のプログラムを作ったのですが、もっと簡単なプログラムにするにはどのようなソースコードにすればいいのでしょうか?
以下、力技で作ったプログラムのソースコードです。
・・・ソースコード・・・
#include<stdio.h>
#include<math.h>
///式を計算する関数を作る。///
void sub(int a, int b, int c, int d) {
///重複なしで演算子の全ての組み合わせを試行し、10になれば式を表示///
if (a + b - c * d == 10)
printf("%d+%d-%d*%d\n", a, b, c, d);
else if (a + (b - (c / d + 0.5) + 0.5) == 10) ///0.5多く引いているので0.5を加える///
printf("%d+%d-%d/%d\n", a, b, c, d);
else if (a + b * c - d == 10)
printf("%d+%d*%d-%d\n", a, b, c, d);
else if (a + (b * c / d + 0.5) == 10) ///商には0.5を加えてから小数点以下切り捨て=四捨五入///
printf("%d+%d*%d/%d\n", a, b, c, d);
else if (a + (b / c +0.5) - d == 10)
printf("%d+%d/%d-%d\n", a, b, c, d);
else if (a + (b / c + 0.5) * d == 10)
printf("%d+%d/%d*%d\n", a, b, c, d);
else if (a - b + c * d == 10)
printf("%d-%d+%d*%d\n", a, b, c, d);
else if (a - b + (c / d + 0.5) == 10)
printf("%d-%d+%d/%d\n", a, b, c, d);
else if (a - b * c + d == 10)
printf("%d-%d*%d+%d\n", a, b, c, d);
else if (a - (b * c / d + 0.5) == 10)
printf("%d-%d*%d/%d\n", a, b, c, d);
else if ((a - (b / c + 0.5) + 0.5) + d == 10)
printf("%d-%d/%d+%d\n", a, b, c, d);
else if (a - (b / c * d + 0.5) == 10)
printf("%d-%d/%d*%d\n", a, b, c, d);
else if (a * b + c - d == 10)
printf("%d*%d+%d-%d\n", a, b, c, d);
else if (a * b + (c / d + 0.5) == 10)
printf("%d*%d+%d/%d\n", a, b, c, d);
else if (a * b - c + d == 10)
printf("%d*%d-%d+%d\n", a, b, c, d);
else if (a * b - (c / d + 0.5) + 0.5 == 10)
printf("%d*%d-%d/%d\n", a, b, c, d);
else if ((a * b / c + 0.5) + d == 10)
printf("%d*%d/%d+%d\n", a, b, c, d);
else if ((a * b / c + 0.5) - d == 10)
printf("%d*%d/%d-%d\n", a, b, c, d);
else if ((a / b + 0.5) + c - d == 10)
printf("%d/%d+%d-%d\n", a, b, c, d);
else if ((a / b + 0.5) + c * d == 10)
printf("%d/%d+%d*%d\n", a, b, c, d);
else if ((a / b + 0.5) - c + d == 10)
printf("%d/%d-%d+%d\n", a, b, c, d);
else if ((a / b + 0.5) - c * d == 10)
printf("%d/%d-%d*%d\n", a, b, c, d);
else if ((a / b * c + 0.5) + d == 10)
printf("%d/%d*%d+%d\n", a, b, c, d);
else if ((a / b * c + 0.5) - d == 10)
printf("%d/%d*%d-%d\n", a, b, c, d);
else { ///全ての条件を満たさなければ何も返さない///
return;
}
}
int main(void) {
///値を格納する変数を0に初期化///
int a, b, c, d = 0;
printf("一桁の整数4つを入力してください。\n");
///1桁の整数4つを入力///
scanf_s("%d %d %d %d", &a, &b, &c, &d);
printf("\n");
///関数呼び出し///
sub(a, b, c, d); ///1桁の整数4つの組み合わせを試行///
sub(a, b, d, c);
sub(a, c, b, d);
sub(a, c, d, b);
sub(a, d, b, c);
sub(a, d, c, b);
sub(b, a, c, d);
sub(b, a, d, c);
sub(b, c, a, d);
sub(b, c, d, a);
sub(b, d, a, c);
sub(b, d, c, a);
sub(c, a, b, d);
sub(c, a, d, b);
sub(c, b, a, d);
sub(c, b, d, a);
sub(c, d, a, b);
sub(c, d, b, a);
sub(d, a, b, c);
sub(d, a, c, b);
sub(d, b, a, c);
sub(d, b, c, a);
sub(d, c, a, b);
sub(d, c, b, a);
return 0;
}
A 回答 (2件)
- 最新から表示
- 回答順に表示
No.2
- 回答日時:
* 一桁の整数4つ、全パターン
int[4] から 4 個とる順列
同じものを含む順列の可能性あるので、重複は除く処理が必要
* 同じ演算子は使用不可、カッコを用いた計算方法は考えない
"+,-,*,/" の 4 個から 3 個とる順列
* int型の変数のみ使用可
整数 2 個で一つの値を表現する有理数で計算する
// 足し算の処理サンプル
typedef struct { int a, b; } rat_num;
rat_num v = {1,3}, w = {3,1};
v.a = v.a * w.b + w.a * v.b;
v.b = v.b * w.b;
printf("%d\n", v.a / v.b);
* 演算子には優先順位がある
LL(1)文法で構文解析する
// 構文例
expr0 := expr1 ( ('+'|'-') expr1 )*
expr1 := expr2 ( ('*'|'/') expr2 )*
expr2 := number
// それぞれに対応する関数を作る
typedef struct { int *nums, *oprs, index, size; } context;
ret_num calc_expr0(context* p); // calc_expr1 で得た値を加算減算する
ret_num calc_expr1(context* p); // calc_expr2 で得た値を乗算除算する
ret_num calc_expr2(context* p); // 現在の位置の数値を得る
// calc_expr0 を実行することで、数式の計算結果を得られる
* 同じものを含む順列
再帰ですべての組み合わせを求める
// 処理例
void permutate(int a[], int s, int t, int n) {
_ int i, j, f, v;
_ if (n < t) {
_ _ v = a[n];
_ _ for (i=n; i<s; i++) {
_ _ _ for (f=0, j=n; j<i; j++) f |= (a[j] == a[i]);
_ _ _ if (f) continue; // 重複させない
_ _ _ a[n] = a[i]; a[i] = v;
_ _ _ permutate(a, s, t, n+1);
_ _ _ a[i] = a[n]; a[n] = v;
_ _ }
_ } else {
_ _ 出力(a, t);
_ }
}
No.1
- 回答日時:
一応、つっこんでおくと
C言語では、
・計算は、演算子一つずつ順番にやります。
・int / int = int です。小数以下は出ません。
・int + double = double です。
・double == int の比較は int → double の型変換が行われて double == double の比較 です。
> else if (a + (b * c / d + 0.5) == 10) ///商には0.5を加えてから小数点以下切り捨て=四捨五入///
では
int t1,t2 ;
double s1,s2 ;
t1 = b*c ; /* int * int = int */
t2 = t1/ d ; /* b * c / d : int / int = int 端数は出ない */
s1 =(double)t2 + 0.5 ; /* b * c / d + 0.5 : int + double = double 整数に+0.5しただけ */
s2 = (double)a + s1 ; /* a + (b * c / d + 0.5) : int + double = double */
if ( s2 == (double)10 ) { /* double == int は double == double で比較。doubleをintに切り捨てたりしない */
と同等になります。
///商には0.5を加えてから小数点以下切り捨て=四捨五入///
なんてことにはなりません。
他も同様です。
スマートにやるなら次のようになるでしょう。
(1)入力した4値の全ての順列パターンに対してループさせる
(2)4つ演算子の全ての順列パターンに対してループさせる
(3) (1),(2)で求めた 4つの値と4つの演算子から式を作り、それを解析して、解析木を作り、計算する。
(4)計算は分数で行う
全体としてはシンプルですが、それぞれの処理が複雑になります。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
コンパイルエラーについて
-
WM_CLOSEで閉じれないウィンド...
-
【C言語教えてください】sin波...
-
cshの文字列操作(0埋め)
-
C言語の勉強しています。すみま...
-
CTRL+Dでループを抜けるには
-
printf で二進表示を行いたい。
-
コマンドラインに出力した文字...
-
2つ分数の四則演算を行うプロ...
-
%P と %X の違い
-
printfの出力内の文字をdefine...
-
アドレスの比較について
-
%dについて
-
このプログラムみてもらえますか?
-
コマンドプロンプトがすぐ消える
-
4の倍数を論理演算で表す。。
-
printfの有無で値が変化する
-
Visual C++でのプログラミング
-
ヘロンの公式を作ったプルグラ...
-
unsigned int型について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
コンパイルエラーについて
-
printf で二進表示を行いたい。
-
c言語でAからZまでを表示する...
-
テキストカーソル位置の取得
-
4の倍数を論理演算で表す。。
-
cshの文字列操作(0埋め)
-
【C言語教えてください】sin波...
-
10個出力で改行したいのですが...
-
wsprintfの書式制御文字列につ...
-
printfの出力内の文字をdefine...
-
error C2143: 構文エラー : ';'...
-
C言語
-
%P と %X の違い
-
strcmp
-
(C言語)めちゃくちゃな値にな...
-
コマンドラインに出力した文字...
-
スレッドとメッセージキューに...
-
printf( " %2d", p * q );
-
C++でfprintfやprintf,fopenな...
-
3つの整数が等しいかどうか調...
おすすめ情報