掲示板ランキング  レギュラー(ブルーマウンテン)  レギュラー(マンデリン)


掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板1

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.7428

digital root
投稿者---ボンバ(2007/05/14 19:13:29)


<digital root>
正整数の 10 進法表現の各桁の和を計算し、その結果が 1 桁になればその数を
digital root という。その結果が2桁以上の場合 1 桁になるまで再帰的に各桁の和を求める、プログラムを作っています。

例:1234 → 10 → 1

作り方が全くわからないので、
だれか、ヒントとかサンプルコード教えていただけませんか??


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:digital root 7429 ぽへぇ 2007/05/14 19:35:06
<子記事> Re:digital root 7430 たかぎ 2007/05/14 19:42:16
<子記事> Re:digital root 7433 επιστημη 2007/05/14 21:55:58


No.7429

Re:digital root
投稿者---ぽへぇ(2007/05/14 19:35:06)


>作り方が全くわからないので、

あなたが使っている開発環境とか、
#「環境(OSとコンパイラ)や症状は具体的に詳しく書きます」を理解していますか?

入力はどうするの(最高何桁になりそうなの)とか、

少しでも書けそうなところはあるもんでしょうに。

整数から各桁の数字を取り出すのはわかる?
(ヒント:与数が0になるまで10で割り続け、1の位を見る)



この投稿にコメントする

削除パスワード

No.7431

Re:digital root
投稿者---ボンバ(2007/05/14 19:43:00)


C言語です。

桁数の制限はありません。
何桁でもOKです。

「与数が0になるまで10で割り続け、1の位を見る」
これは学校でもヒントで与えられたんですが、全く書き方がわかりません。。

教えてください。


この投稿にコメントする

削除パスワード

No.7432

Re:digital root
投稿者---たかぎ(2007/05/14 20:05:37)
http://takagi.in/


>桁数の制限はありません。
>何桁でもOKです。

この部分が一番難しそうですね。
アドレス空間の限界による制約は許してもらうにしても、桁数制限なしの加算を行うには、多倍長演算を実装する必要があります。「多倍長演算」をキーワードに検索してみてください。




この投稿にコメントする

削除パスワード

No.7430

Re:digital root
投稿者---たかぎ(2007/05/14 19:42:16)
http://takagi.in/


>作り方が全くわからないので、

1. C言語の入門書を2,3冊読む。
2. とりあえず再帰は考えずに、1回目だけの処理を作ってみる。
3. 再帰的に処理するように変更する。

この手順でどうにかなりませんか?
とりあえず一通り実践してみて、それでも分からなければ再質問してください。




この投稿にコメントする

削除パスワード

No.7433

Re:digital root
投稿者---επιστημη(2007/05/14 21:55:58)
http://blogs.wankuma.com/episteme/


int digital_root(数 n) {
 if ( n が一桁じゃない ) {
  return digital_root(nの各桁を全部足したもの);
 }
 return n; // 一桁ならおしまい。
}



この投稿にコメントする

削除パスワード

No.7435

Re:digital root
投稿者---ボンバ(2007/05/14 23:45:36)


>int digital_root(数 n) {
> if ( n が一桁じゃない ) {
>  return digital_root(nの各桁を全部足したもの);
> }
> return n; // 一桁ならおしまい。
>}


なるほどぉーー!!!

私が頑張って作ったものはこんなものになりました。

#include<stdio.h>
#define SIZE 255
int divide(int n,int *a) {
int c,d;
for(c=0,d=10;n>0;) {
*a=n%d;    
n=n/d;    
*a++;
c++;
}
return c;     
}

int digital_root(int n) {
int a[SIZE],ans,c,i;
ans=n;
for(;ans>=10;) {
c=divide(ans,a);
for(i=0,ans=0;i<c;i++) {
ans+=a[i];
}
}
return ans;
}

int main(void) {
int ans,n;
printf("n=");
scanf("%d",&n);

if(n<=0) {
printf("Error");
exit(-1);
}

ans=digital_root(n);
printf("digital_root(%d)=%d\n",n,ans);
return 0;
}

どうでしょうか???
チェックお願いします。自分なりにとってもがんばりました。。。


この投稿にコメントする

削除パスワード

No.7436

Re:digital root
投稿者---Hermit(2007/05/15 01:42:32)


アドバイス通りきちっと・・・ですね(^^;

一旦、全ての数を足し合わせていますが、
一桁ずつ足し合わせていっても、同じ結果になるんじゃなかったかな。

int digital_root (int n) {
  while (n > 9)
    n = n / 10 + n % 10;
  return n;
}

再帰は使ってませんが、無理矢理再帰を使うのも簡単かと思います。

また、入力が文字列であるなら、
#include <stdio.h>
#include <ctype.h>
int main() {
  int digit = 0;
  char ch;
  while (isdigit(ch = fgetc(stdin))) {
    digit += ch - '0';
    if (digit > 9) 
      digit -= 9;
  }
  printf("%d",digit);
  return 0;
}

でもいいのではないかな。(こっちも再帰してない)


この投稿にコメントする

削除パスワード

No.7437

Re:digital root
投稿者---ぽへぇ(2007/05/15 06:46:07)


>チェックお願いします。自分なりにとってもがんばりました。。。

>int n;
>scanf("%d",&n);
後から勝手に変な制限をつけられてもね。

>桁数の制限はありません。
>何桁でもOKです。
9999999999999(以下 1万桁くらい続く) とか、試した?

あえて突っ込んでいるのでそのつもりで。



この投稿にコメントする

削除パスワード

No.7438

Re:digital root
投稿者---επιστημη(2007/05/15 07:32:49)
http://blogs.wankuma.com/episteme/


>どうでしょうか???

ダメダメです。「何桁でもOK」を満たしません。
これだと10桁そこそこでしょう。



この投稿にコメントする

削除パスワード

No.7439

Re:digital root
投稿者---あ(2007/05/15 09:13:51)


みんなキビシーなww
とりあえず32ビット範囲でOKじゃまいか。
問題出した先生も、そこまで考えてないだろ。
文句は先生に言わないと。


この投稿にコメントする

削除パスワード

No.7440

Re:digital root
投稿者---επιστημη(2007/05/15 10:33:15)
http://blogs.wankuma.com/episteme/


>とりあえず32ビット範囲でOKじゃまいか。
>問題出した先生も、そこまで考えてないだろ。

まぁ、intなりlongなりの範囲で"何桁でもOK"って意味でしょね。



この投稿にコメントする

削除パスワード

No.7442

Re:digital root
投稿者---円零(2007/05/15 21:37:27)


>まぁ、intなりlongなりの範囲で"何桁でもOK"って意味でしょね。

そもそも、処理されるデータの最初の形は整数型なんでしょうかね?
文字列で入力して処理を行うのであれば、最初の合計値が整数型の範囲内にあればいい、というくらいまでは楽に実現できそう。
その程度でも、オーバーフローさせるのは人力の入力ではほとんど無理、になりますね。



この投稿にコメントする

削除パスワード

No.7443

Re:digital root
投稿者---Hermit(2007/05/15 22:45:49)


>文字列で入力して処理を行うのであれば、最初の合計値が整数型の範囲内にあればいい、というくらいまでは楽に実現できそう。

7436 で私が書いた2番目のプログラムは、何か間違ってた?
(char ch; は、int ch; の間違いではあるんだけど)

最初の合計値にせずに、2 値づつ合計値を処理していけば、18 を超える理由は無いと思うのだが。

それとも、必ず再帰を使う様にする為?


この投稿にコメントする

削除パスワード

No.7444

Re:digital root
投稿者---円零(2007/05/16 00:49:31)


>7436 で私が書いた2番目のプログラムは

失礼、スレッド全体を読んでませんでした。


この投稿にコメントする

削除パスワード

No.7445

Re:digital root
投稿者---Hermit(2007/05/16 06:46:33)


間違ってたからって訳ではないんですね。

自分で自信を持って書いてても、間違ってるって事は良くあるので、
やっちまったかなって、ちょっと不安だったのですが、
そういう意味でないなら安心しました。


この投稿にコメントする

削除パスワード

No.7441

Re:digital root
投稿者---たかぎ(2007/05/15 11:13:44)
http://takagi.in/


特定の誰かのことではありませんが...

>みんなキビシーなww
>とりあえず32ビット範囲でOKじゃまいか。

getsやscanfでのバッファあふれに対しては目くじらを立てるのに、数値のオーバーフローに対しては甘く考えている人が多いように思います。
scanfで%dを使ったとき、値が表現できない場合の動作は未定義になります。
ましてや環境が指定されていないのですから、(未定義の動作という意味で)バッファあふれと同程度に深刻な問題がありますね。



この投稿にコメントする

削除パスワード

No.7451

Re:digital root
投稿者---金魚ちゃん(2007/05/19 17:44:23)


整数型でのサンプルです。
ループを用いて求めています。再帰はご自分で。

#include <stdio.h>

int main( void )
{
 int d, data;
 
 while ( scanf(" %d",&data) == 1 ){
  if ( data < 0 ){ ←負数を入力すると終了
   break;
  }
  for ( d = data ; d >= 10 ; ){ ←ループで求める
   printf( "%d ", d );
   d = (d / 10) + (d % 10); ←ここがポイント!
  }
  printf( "\n" );
  printf( "data=%d(%d)\n\n>", data, d ); ←結果表示(data=入力値,d=digital root)
 }
 return 0;
}

int、long 型で試して見て下さい。
文字列を使えば入力桁数には制限はなくなると思います。
ただし、ソースを書き換える必要が出てきますが…。
それでは。頑張ってな。



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧





掲示板提供:(有)リアル・インテグリティ