答えを0にするこまち算のプログラムを組んでみたのですが、ここからどうしても進まなくなってしまいました。
自分ではいけるかなと思ったのですが、9-8-7+65-4321=9など答えがありえない数になってしまいます。
どこがいけないか教えてください。むしろ最初から組み直した方がよいのでしょうか…
#include <stdio.h>
int cul();
int num[9] ={9,8,7,6,5,4,3,2,1};
int total;/**/
int kigou[8]={0,0,0,0,0,0,0,0};
int main(){
for(kigou[0]=0;kigou[0]<3;kigou[0]++){
for(kigou[1]=0;kigou[1]<3;kigou[1]++){
for(kigou[2]=0;kigou[2]<3;kigou[2]++){
for(kigou[3]=0;kigou[3]<3;kigou[3]++){
for(kigou[4]=0;kigou[4]<3;kigou[4]++){
for(kigou[5]=0;kigou[5]<3;kigou[5]++){
for(kigou[6]=0;kigou[6]<3;kigou[6]++){
for(kigou[7]=0;kigou[7]<3;kigou[7]++){
keisan();
}
}
}
}
}
}
}
}
return 0;
}
int keisan(){
int n =0;
int flag = 0;
int t = 0;
int i = 0;
total = num[0];
/* for (n=0;n<9;n++)
printf("kigou[%d] == %d",n,kigou[n]);確かめ*/
for(;n<8;n++){
if(kigou[n] == 0 && n == 0){
total = total * 10 + num[n+1];
for(flag=1;kigou[n+flag]==0 && (n+flag)<9 ;flag++){
total = total * 10 + num[n+flag+1];
}
n = n + flag;
}
flag=0;
if(kigou[n]!= 0){
for(flag=1;kigou[n+flag]==0 && (n+flag)<9 ;flag++){
t = num[n+1] * 10 + num[n+flag+1];
}
n = n+ flag;
total = total + t;
}
}
/*0になる計算式の表示*/
kigou[8]=2;/*表示しないために空白を入れる*/
if(total==0){
for(i=0;i<9;i++){
printf("%d",num[i]);
if(kigou[i]==0)
printf("+");
if(kigou[i]==1)
printf("-");
if(kigou[i]==2)
printf("");
}
printf("=%d\n",total);
}
return 0;
}
A 回答 (5件)
- 最新から表示
- 回答順に表示
No.5
- 回答日時:
こんにちは。
早速のお礼ありがとうございます。
この問題は“+、-のみ”等の規制をどんどん外していくことで
難易度がだんだん上がっていきます。
そして自分で問題を設定して考えていくことは、演習問題をただこなして
いくよりも何倍もの価値があります。
最初は難しいかもしれませんが、頑張って是非解決してください。
プログラミングへの自信と実力が必ずつきます。
c言語を勉強し始めて1年、プログラミングに向いていないのかと正直自信をなくすこともありますがそう言っていただけるととてもやる気が出ます。
とりあえず今は目先の小町算を解くことに集中してみますね。
ありがとうございました。
No.4
- 回答日時:
「数式を評価するルーチン」を使ってみた。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
double expr(char *buf,char **p);
double expr3(char *buf,char **p)
{
double a;
*p=buf;
while (**p == ' ') (*p)++;
a=strtod(*p,p);
while (**p == ' ') (*p)++;
return a;
}
double expr2(char *buf,char **p)
{
double a;
*p=buf;
switch (**p) {
case '(':
while (**p == ' ') (*p)++;
a=expr(++(*p),p);
while (**p == ' ') (*p)++;
if (**p==')') (*p)++;
return a;
case '+':
return expr(++(*p),p);
case '-':
return -1.0 * expr(++(*p),p);
}
return expr3(*p,p);
}
double expr1(char *buf,char **p)
{
double a,b;
*p=buf;
while (**p == ' ') (*p)++;
a=expr2(*p,p);
for(;**p;) {
while (**p == ' ') (*p)++;
switch (**p) {
case '*':
b=expr2(++(*p),p);
a*=b;
continue;
case '/':
b=expr2(++(*p),p);
a/=b;
continue;
}
break;
}
return a;
}
double expr(char *buf,char **p)
{
double a,b;
*p=buf;
while (**p == ' ') (*p)++;
a=expr1(*p,p);
for(;**p;) {
while (**p == ' ') (*p)++;
switch (**p) {
case '+':
b=expr1(++(*p),p);
a+=b;
continue;
case '-':
b=expr1(++(*p),p);
a-=b;
continue;
}
break;
}
return a;
}
void main(void)
{
double ans;
int i,o1,o2,o3,o4,o5,o6,o7,o8;
char str[] = {"9 8 7 6 5 4 3 2 1\0"};
char ope[] = {" +-*/"};
char buf1[256];
char buf2[256];
char *p,c;
strcpy(buf1,str);
for (o1 = 0;o1 < 5;o1++) {
buf1[1] = ope[o1];
for (o2 = 0;o2 < 5;o2++) {
buf1[3] = ope[o2];
for (o3 = 0;o3 < 5;o3++) {
buf1[5] = ope[o3];
for (o4 = 0;o4 < 5;o4++) {
buf1[7] = ope[o4];
for (o5 = 0;o5 < 5;o5++) {
buf1[9] = ope[o5];
for (o6 = 0;o6 < 5;o6++) {
buf1[11] = ope[o6];
for (o7 = 0;o7 < 5;o7++) {
buf1[13] = ope[o7];
for (o8 = 0;o8 < 5;o8++) {
buf1[15] = ope[o8];
for (i = 0,p = buf2;;i++) {
c = *p = buf1[i];
if (c != ' ') p++;
if (c == '\0') break;
}
ans = expr(buf2,&p);
if (*p) printf("%s以降が構文エラー\n",p);
if (ans == 0.0) printf("%s=0\n",buf2);
}
}
}
}
}
}
}
}
}
数式を評価するルーチンというものがあるんですね…。
ルーチンの意味が分からず辞書で探してしまうくらい勉強が足りない私ですが、早くこんなプログラムが組めるように頑張ります。
参考にさせていただきますね。
回答ありがとうございました。
No.3
- 回答日時:
こんにちは。
質問の題名は“C言語で小町算”とか“小町算”にしてください。
閲覧するかどうか、見る人がすぐに判断できますので。
私だったら設計からやり直します。掛け算、割り算に対応できないからです。
今のソースはあくまで左から演算できることが前提となっています。
設計する前に、まず手計算をする場合の基本を考えます。
パッと考えた結果、以下の規則が思い浮かびました。
・基本的に左から演算する
・×、÷>+、-
・カッコがあった場合はカッコ内を先にする
これを元に考えて以下の処理の流れにします。
1.数値と演算子に分ける
2.演算子に順位を付ける
3.順位の高い演算子から演算を行う
通常はカッコを付けないと思いますが、付けても順位を上げることで
対処が可能だと思います。
あとは処理を細かくしてソースを書けば終わりです。
ご参考までに。
ご指摘ありがとうございます。
次回から気をつけます。
私の説明不足で申し訳ありません。
足し算・引き算のみの計算での小町算です。
しかしとても参考になりました。
今のプログラムが完成したら掛け算・割り算の小町算も作ってみようと思います。
ありがとうございました。
No.2
- 回答日時:
>for(flag=1;kigou[n+flag]==0 && (n+flag)<9 ;flag++){
>total = total * 10 + num[n+flag+1];
>}
n+flag は 最大 8 になる場合があるのですね。ということは、
num[n+flag+1] は num[9] にアクセスする場合がありますね。
ところが、
>int num[9] ={9,8,7,6,5,4,3,2,1};
num[8] までしかありません。num[9] は定義範囲の外です。
こういった点を含めて、
>最初から組み直した方がよいのでしょうか…
そのとおりだと思います。
指摘されるまで気づきませんでした。
行き当たりばったりで組んでいたのもあり、お恥ずかしいかぎりです。
やはり最初から組み直してみますね。
ありがとうございました。
No.1
- 回答日時:
一度ネットで検索してそのページも見たのですが、自分のやり方と全く違うようでしたのでその時はあまり読まなかったのです…。
やはり自分だけではできないので一度しっかり読んでみますね。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# 並列プログラミングのπ計算について 1 2022/07/16 22:30
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
str系関数を使わずに二つの文字...
-
配列をnビットシフトする
-
Win32APIでのエディットボック...
-
型変換
-
全角文字を含んだ文字の並びを...
-
c言語です。
-
下記のプログラムがコンパイラ...
-
c言語の問題の説明、各所ごとに
-
strlen関数と同じ働きをする関...
-
C言語で、入力された、文字列を...
-
double型の値をchar配列に変換...
-
C言語の入力した文字を反転させ...
-
enumの記述について。
-
c言語でソーベルフィルタが作り...
-
宣言による処理の重さ
-
文字列の中から必要なデータを...
-
CStringをwchar_tに変換したい
-
間接操作のレベルとは
-
'const char *' 型は 'char *' ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fgetsなどのときのstdinのバッ...
-
charでの計算?
-
C言語のfor文です。 繰り返しの...
-
charからLPTSTRへの変換方法
-
文字列から空白を取り除きたい...
-
C言語の入力した文字を反転させ...
-
'const char *' 型は 'char *' ...
-
配列をnビットシフトする
-
str系関数を使わずに二つの文字...
-
int main()の・・・
-
atoi( ) の反対をやりたい
-
c++ 文字列を入力して、一文字...
-
CStringをwchar_tに変換したい
-
switch文で文字を比較すること...
-
干支のプログラム
-
絶対パスからのファイル名の切...
-
3桁区切(コンマ)記号をつけ...
-
間接操作のレベルとは
-
間接参照のレベルが異なっています
-
【C言語】文字型と整数型の違い
おすすめ情報