#include<stdio.h>
#define KETA 9
#define SIN_SU 3
#define GOOD 100
int next(int symbol[]);
void int_set(int symbol[]);
void myprint(int symbol[]);
int check(int symbol[]);
main()
{
int symbol[KETA];
int_set(symbol);
do{
if(check(symbol))
myprint(symbol);
}while(next(symbol));
}
int next(int symbol[])
{
int i=KETA;
do {
if(++symbol[i]<SIN_SU) return symbol;
symbol[i]=0;
}while(i--);
return 0;
}
void int_set(int symbol[])
{
int i;
symbol[0]=1;
for(i=1;i<KETA;i++) symbol[i]=0;
}
void myprint(int symbol[])
{
int i;
for(i=0;i<KETA;i++) {
if(symbol[0]==1) ;
else if(symbol[i]==1) printf("+");
else if(symbol[i]==2) printf("-");
printf("%d",i+1);
}
}
int cheak(int symbol[])
{
int num=0;
int result=0;
int i;
for(i=0;i<KETA;i++) {
if(symbol[i]==0) num=10*num+(i+1);
else{
if(symbol[i]==2) {
result+=-1*num;
num=i+1;
}
else {
result+=symbol[i]*num;
num=i+1;
}
}
}
if(result==GOOD) return 1;
else return 0;
}
このプログラムの関数nextのところのreturn symbolが
思うとおりに動きません。どなたか教えていただけないでしょうか?
No.5ベストアンサー
- 回答日時:
No.2 です。
> いろいろと修正しましてコンパイルできるようになったのですが答えが3つずつ出てしまいます。原因がわかりません・・。どうしてでしょうか?
int* next(int symbol[])
{
int i=KETA - 1;
が正解です。
ここ以外のところでは、symbol[0] から symbol[KETA - 1] までを使っていますよね?
symbol[KETA] は、そのさらにひとつ下の桁です。
なので、この桁があふれるまで3回分かかるのです。
int symbol[KETA] で確保して、symbol[KETA] にアクセスすると、良くないことがおきそうですが、たまたま運良く(運悪く)実害が見えなかったのでしょう。
No.4
- 回答日時:
#3です。
訂正します。
>1~9の数字を for (i = 1; i <= KETA; i++) などのループで処理する事を考えると、symbol[0]を使用しない方が自然な形になるかもしれません。
これは無かった事にして下さい(笑
No.3
- 回答日時:
小町算は123456789の数字の間に空白または演算記号を入れるって事ですよね?
そうすると、int symbol[KETA]; は int symbol[KETA-1]; と宣言するか、symbol[0]またはsymbol[KETA-1]は使用しない事になると思います。
1~9の数字を for (i = 1; i <= KETA; i++) などのループで処理する事を考えると、symbol[0]を使用しない方が自然な形になるかもしれません。
問題のnext関数ですがsymbolを返す必要はありません。symbolに1を加える典型的な方法を記しておきます。(要素数はKETAとしています)
int next(int symbol[])
{
int a = 1, i, n;
for (i = 0; i < KETA; i++) {
n = symbol[i] + a;
symbol[i] = n % SIN_SU;
a = n / SIN_SU;
}
return !a;
}
No.2
- 回答日時:
int next(int symbol[])
{
int i;
symbol[KEKA]++;
for (i = KETA; (i >= 2) && (symbol[i] >= SIN_SU); i--)
{
symbol[i] = 0;
symbol[i - 1] ++;
}
if (symbol[0] != 1) return 0;
return 1;
}
こんな感じでしょうか。(チェックしていません)
気持ちとしては、
・9個の配列に なにもない、+、-をそれぞれ配置する。
・この配列を更新するのが楽なように、それじれ、0, 1, 2にした。
・100100100 なら、1+234+567 (でも、これだと、9桁めが0だと問題ですね)
・問題の next は、今の符号配置から次の符号配置を計算する。これを、3進数の多桁演算でやってみた。
・多桁演算をして、桁がオーバーフローしなかったら配列を返す
という感じですね。
まず、配列は、特殊な事情による、実質参照渡しになります。このため、関数側でいじった内容はそのまま帰ります。従って明示的に配列を返す必要はありません。(そもそも、next が返すのは、int のはず)
また、もとの書き方では、「1桁でもOKの桁があれば直ちに終了」しますし、さらに、繰り上がりもしていません。
(その桁が3に達したら、その桁を0にしているだけで、次の桁をインクリメントしていない)
というところでしょうか。
あと、「思うとおりに動きません」というのは、通常実行してみたら、動きがおかしいというレベルで使います。
もとのソースは、多分、コンパイルが通っていませんよね。
あと、特に check() の計算は面倒そうですね。
この回答への補足
いろいろと修正しましてコンパイルできるようになったのですが答えが3つずつ出てしまいます。原因がわかりません・・。どうしてでしょうか?
#include<stdio.h>
#define KETA 9
#define SIN_SU 3
#define GOOD 100
#define TRUE 1
#define FALSE 0
int* next(int symbol[]);
void int_set(int symbol[]);
void myprint(int symbol[]);
int check(int symbol[]);
main()
{
int symbol[KETA];
int_set(symbol);
do{
if(check(symbol))
myprint(symbol);
}while(next(symbol));
}
int* next(int symbol[])
{
int i=KETA;
do {
if(++symbol[i]<SIN_SU) return symbol;
symbol[i]=0;
}while(i--);
return 0;
}
void int_set(int symbol[])
{
int i;
symbol[0]=1;
for(i=1;i<KETA;i++) symbol[i]=0;
}
void myprint(int symbol[])
{
int i;
for(i=0;i<KETA;i++) {
if(symbol[i]==1) if(i==0);
else printf("+");
else if(symbol[i]==2) printf("-");
printf("%d",i+1);
}
printf(" = %d\n",GOOD);
}
int check(int symbol[])
{
int num=0;
int result=0;
int tmp=0;
int i;
for(i=0;i<KETA;i++) {
if(symbol[i]==0) num=10*num+(i+1);
else{
if(tmp==2) {
result+=-1*num;
tmp=symbol[i];
num=i+1;
}
else {
result+=tmp*num;
tmp=symbol[i];
num=i+1;
}
}
}
if(tmp==2) result +=-1*num;
else result += tmp*num;
if(result==GOOD) {
return TRUE;
}
else return FALSE;
No.1
- 回答日時:
next関数の返り値を
while(next(symbol))
と使っている所を見ると、0か非0(と言うか、TRUEかFALSE)を返すべき関数として作ったのですよね?
なのに、何故
return symbol;
などと「配列へのポインタ」を返そうとするのか、理解に苦しみます。
(ぶっちゃけ、何がしたいのか、理解に苦しみます)
「呼び出し元での関数の呼び方」と「関数が返すべき返り値」の整合性が取れておらず、全体の設計が出来ていないと思われます。
フローチャート図の書き方など、プログラムの設計方法の基礎から習得し直すべきです。
返信ありがとうございます!まだ勉強をはじめたばかりで見苦しくて申し訳ありません。
next関数は100000000~222222222までを調べる関数なのです。これは1が+,2が-,0が何もないと思って内部データをあらわしています。そして最下位から1ずつインクリメントして調べようという関数のつもりで作りました。そこでreturnで配列を返すことによってこの範囲の中ならループを続けるとしたかったのです。
説明も下手で申し訳ありません。もう一度考え直してみます!ありがとうございました!
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# C言語でif文が予想と違う動きをする件について7 4 2023/03/20 00:26
- C言語・C++・C# 質問です 下記のコードを分かりやすく解説お願いします 初心者です #include ‹stdio.h 3 2022/05/26 22:03
- その他(プログラミング・Web制作) Pythonで会員サイトの自動ログイン ID Nameがない 1 2022/12/16 02:09
- C言語・C++・C# プログラムの時、フローチャートはどうなりますか?図でお願いします。 int main(void) { 1 2022/10/01 22:45
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- その他(プログラミング・Web制作) 十進BASICでの再帰についての質問です。 2 2022/11/18 09:17
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
「指定されたキャストは有効で...
-
比較回数と交換回数表示について
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
#define _CRT_SECURE_NO_WARNIN...
-
std::set<int> で、ある値が何...
-
C言語で三目並べをするプログラ...
-
商と剰余を同時に求める(C言語)
-
if と配列の組み合わせ
-
【C++】関数ポインタの使い方
-
並列プログラミングのπ計算につ...
-
c言語
-
HANDLEて何ですか?
-
read関数をノンブロッキングで...
-
卒業研究でよく分からないとこ...
-
DLLをGetProcAddress()で実行で...
-
GlobalAllocの変数を関数に引き...
-
シグマ公式・・・C言語
-
ファイルから読みこむ方法
-
c言語の問題です
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語での引数の省略方法
-
#define _CRT_SECURE_NO_WARNIN...
-
「指定されたキャストは有効で...
-
C言語 配列と関数の練習問題
-
複数桁10進数の*桁目だけを抽出...
-
(int *)の意味
-
if と配列の組み合わせ
-
ラップ関数とはどんなものですか?
-
卒業研究でよく分からないとこ...
-
【C++】関数ポインタの使い方
-
c言語
-
足して100になるような乱数のア...
-
C言語初心者です、、、お助けく...
-
数字列を3桁ごとにカンマで区切...
-
C言語 エラーの原因がわからな...
-
実数の整数部,小数部の取得
-
課題でつまってます・・・
-
商と剰余を同時に求める(C言語)
-
C言語の配列をC++のvectorに高...
-
std::set<int> で、ある値が何...
おすすめ情報