• 締切済み

c言語 至急お願い致します

10000以下の自然数のうち素因数分解を行ったときにその因子の数が最多となる数を求め,その数,因子の数,素因数分解の結果を表示するプログラムを作成して下さい. 出力形 8192 = 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 因子数:13

みんなの回答

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.9

2 で割るのを忘れてました.

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.8

そうか, 考えてみれば #include <stdio.h> #include <stdlib.h> int main() { int val = 1; int factors, i; for (factors = 0; (val *= 2) <= 10000; ++factors) { ; } printf("%d = 2", val); for (i = 1; i < factors; ++i) { printf(" * 2"); } printf("\n因子数: %d\n", factors); return EXIT_SUCCESS; } でいいのか. 本題とは全く関係ないのですが, 出力部分があやしい気がします>#7. 符号なしなら d じゃなくて u だろとか uint64_t のフラグは l でいいのかとか. あと, 実は g++ でも Windows だと危険だったりします.

回答No.7

> 素因数分解については理解できています > なので10000を素因数分解するプログラムは作れるのですが、それ以下を判別して求めるプログラムは全くわかりません と言うなら、まずはそのプログラムをどれかの補足に載せましょうよ。 素因数分解ができるなら、因子数もわかるでしょうから、あとはそれを比較する部分を書くだけです。 まずは素因数分解した時の因子数を数えるプログラムを書いてはいかがでしょうか。C言語で書くとしたら、素因数分解の結果を覚えておくメモリーの管理が面倒くさいはずなので、とりあえずそれは後回しにしましょう。 次に、因子数の最大値を求めるプログラムを書いてみましょう。 それから、後回しにしていた素因数分解した結果の記録と表示を作ってみましょう。 C言語で書くならなら、mainあたりで因子数が最大値を達成した時の値を覚えておく配列と各因数分解の時に使用する配列の2つを用意して、これまでの最大値を超える因子数が出るごとにコピーしておくとかになるでしょうね。長さを管理する変数をそれぞれに用意するか、それぞれの配列の最後に番兵として-1や0などを入れるかですね。(あるいは、単に2つ配列を用意し、作業用の配列を指すポインターとこれまでの最大値を超える因子数が出た時の配列を指すポインターを付け替えながら動作するか。) 10000以下の自然数なので、どんなに効率が悪いプログラムで現実的な時間で終わると思いますが、もしどうしても遅い場合は100などもう少し小さい数でプログラムを書いて、高速化方法を検討し、10000にチャレンジしましょう。 高速化で自分がまず思いつくのはエラトステネスの篩のように平方根までしか素因数分解のときに試さないというものです。 あと、再起を使ったプログラムを書いている場合、メモリーがある程度あり、メモリーの管理がかったるくないならメモ化も検討します。 ちなみに、以上のことをC++で書いてみるとこんな感じです。 #include <cmath> #include <cstdio> #include <unordered_map> #include <vector> using std::vector; using std::printf; std::unordered_map<uint64_t, vector<uint64_t> > memo; vector<uint64_t> factor(uint64_t num) { if (num < 2) { // i.e. 0, 1. return vector<uint64_t>(); } auto got = memo.find(num); if (got != memo.end()) { return got->second; } uint64_t max_div = static_cast<uint64_t>(std::sqrt(num)); for (uint64_t i = 2; i <= max_div; i++) { if (num % i == 0) { vector<uint64_t> result = factor(num / i); result.push_back(i); memo.emplace(num, result); return result; } } vector<uint64_t> ret; ret.push_back(num); memo.emplace(num, ret); return ret; } int main(void) { uint64_t max_value; vector<uint64_t> max_factored; for (uint64_t i = 2; i <= 10000; i++) { vector<uint64_t> factored = factor(i); if (factored.size() > max_factored.size()) { max_value = i; max_factored.swap(factored); } } printf("%ld = ", max_value); for (size_t i = 0; i < max_factored.size(); i++) { if (i != 0) { printf(" * "); } printf("%ld", max_factored[i]); } printf("\n#elms: %zd\n", max_factored.size()); return 0; } ちなみに、unordered_mapやautoを使っているので、C++11を理解しないコンパイラーだとコンパイルできません。-std=c++11をつけると対応したg++やclang++でコンパイルできると思います。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.6

全部まとめてやろうとするから、わからなくなるのです。 「プログラム」を作ろうとするあら、わからなくなるのです。 ・問題を細かくわけて考える ・まずは「やり方」を考える。その内容を「プログラミング言語で記述する」 というのがプログラミングのコツです。 素因数分解はできる、ということなら 1を素因数分解→因子数1→ 暫定最大値1,暫定最大因子数1 2を素因数分解→因子数1→ 暫定最大値1,暫定最大因子数1 3を素因数分解→因子数1→ 暫定最大値1,暫定最大因子数1 4を素因数分解→因子数2→ 暫定最大値4,暫定最大因子数2 5を素因数分解→因子数1→ 暫定最大値4,暫定最大因子数2 ... 10000を素因数分解→因子数??→ 暫定最大値??,暫定最大因子数?? という「やり方」ができる、ということです。 これを「プログラミング言語で記述する」ことは簡単でしょう。 これでは効率が悪い、もっと効率よくしたい、という場合でも、まずは「やり方」を考えることです。 例えば ・素数は因子が1つしかないので最大値の候補とはならない →最初に素数一覧を作れば、その一覧にあるものは候補から取り除ける →効率のよい素数一覧作成方法は? ・8192=2^13で因子数13. log2(10000)=13.28....。ただの偶然でしょうか?

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.5

1の素因数分解をする 2の素因数分解をする ... 10000の素因数分解をする その中で一番因子の数が多かったのはどれ? という問題なんですから素因数分解理解してるのならできるんじゃ?

回答No.4

> 素因数分解については理解できています > なので10000を素因数分解するプログラムは作れるのですが じゃ、それ見せて。

  • ts3m-ickw
  • ベストアンサー率43% (1248/2897)
回答No.3

素因数分解の方法と再帰プログラムの基本さえ判ってれば30分もかからないで作れるね。 参考になるようにPHPで書いてみた。C言語が読めるならPHPでも読めるでしょう。 でも面倒なので因子数の最大を求めてない。出力フォーマットも合わせてない。 あくまでも参考にしてくださいな。 <?php function decomposition ($val, $div, $cnt) { if ($val==0 || $val==1) print "因子数 $cnt\n"; else if ($val % $div ==0) { $cnt ++; print $div.","; decomposition ($val/$div, $div, $cnt) ; } else decomposition ($val, $div+1, $cnt) ; } for ($i=10; $i<10001; $i++) { print "$i,"; decomposition ($i, 2, 0); } ?> 出力(一部抜粋) 8192,2,2,2,2,2,2,2,2,2,2,2,2,2,因子数 13

回答No.2

出来る人に10万円くらい小遣いを渡して作ってもらいましょう。

  • hitomura
  • ベストアンサー率48% (325/664)
回答No.1

> プログラムを作成して下さい 嫌です。 あなたのこの質問は何らかの課題の丸投げにしか見えません。 別に課題だから答えないというのではありません。あなたが悩んでここまでしかできなかったというコードと一緒に質問されたならば、私たち回答者は(少なくとも私は)あなたが悩んでいることについて喜んでアドバイスするでしょう。 しかし、丸投げの質問に対して答をポンと渡すと結局はその当人のプログラミング技術の向上のためにならないことを、プログラミング系の回答者は実体験などから身に染みて実感しています。 だから、ことプログラミング関係の質問の場で課題の丸投げは嫌われますし、私も嫌いです。 あなたがこの課題に対してどんなコードが書けたかを補足願います。

sensuikan168
質問者

補足

素因数分解については理解できています なので10000を素因数分解するプログラムは作れるのですが、それ以下を判別して求めるプログラムは全くわかりません アドバイスしていただけると幸いです

関連するQ&A

  • 二重ループを使うプログラムについて(C言語)

    素因数分解するプログラムで、例えば360を入力したとき、 2^3 * 3^2 * 5^1 と表示するプログラムを作りたいのですが、scanfとprintfの部分は分かるのですが、肝心の二重ループの部分が分かりません…。 最後に*が表示されないようにするというのが条件なのですが、初心者で慣れてないので、詳しく教えていただけないでしょうか?

  • C言語

    これで入れた数字を素因数分解する事が出来ません。また間違っている理由がわからないのでご指摘お願いします。

  • C言語 因数分解

    素因数分解する事が出来ません。また間違っている理由がわからないので何をどう直せば良いか理由を付けてご指摘お願いします。

  • 素因数プログラムで、間違えて因数4で割らない

    練習問題 5-15  2以上の数値を入力し、素因数分解した結果を表示しなさい。    疑問ですが、素因数分解なので割る数字は、2.3.5.7.・・・の自分の数字しか割りきれない数字で  割ります。それでは、以下のプログラムはどこでそれを判断しているのでしょか?  4で割ろうとしないのは、どこのプログラムが司っているのでしょうか  もし!見えない取り組みがあれば宜しくお願いします。  以下プログラムです。 1) int n, x; 2) scanf("%d", &n ); 3) for( x = 2 ; n > 1 ; x++ ){ 4) while( ( n % x ) == 0 ){ 5) printf( "%d ", x ); 6) n /= x; } }

  • C言語をお願いします

    関数の使い方が分かりません、お知恵を貸してください 問題 一桁の整数を入力。 その数を起点として5の段までの九九の表を表示するプログラムを作成。 条件が4つ。 ・下記の実行結果のように表示しなさい。 ・タイトル行(1・・・5)の表示は、main 関数で行う。 ・入力した数を起点とした5の段までの九九の表を表示する関数 func99 を作る。 ・そのうち乗算部分は、func_mul 関数を作る。 5(入力) 実行例 1 2 3 4 5 //ここはプリントで出力 5 10 15 20 25 6 12 18 24 30 7 14 21 28 35 8 16 24 32 40 9 18 27 36 45 10 20 30 40 50 数字部分は%5dでお願いします

  • C言語の授業で

    C言語の授業で -------------------- 3以上の整数を入力してください:10 素数は以下の数です: 7 5 3 2 素数は4個ありました -------------------- という感じの、入力した数以下の素数を表示するプログラムをwhile文を用いて作成するように言われたんですが・・・。 まず、while文と素数を表示するプログラムがよくわからないので、もう何をすればいいのか・・・。 どうか、ご教授お願いします。

  • C言語についてなんですが

    プログラムの作成で分からないところがあります。 「二つの整数値を読み込み、小さいほうの数以上で大きい数以下の 整数を全て加えた値を表示するプログラムをdo文を使って 作成せよ。」 下の図のようにしたいです。 2つの整数を入力せよ。 整数A:37 整数B:28 28以上37以下の全整数の和は325です。 よろしくお願いします。

  • c言語がわかりません。

    (1)入力された文字列(10文字以下)の`a`の文字を除き、結果を表示するプログラムを作成する。 (2)入力された文字列について、数文字(0から9)の各々の出現個数と、それ以外の文字の出現個数をカウントし表示するプログラムを作成する。

  • C言語を始めよう!

    C言語を始めよう! http://www.forest.impress.co.jp/article/2002/10/24/cwohajimeyou.html を使用しています。 NT4/2000/XP で、16 ビットプログラムの実行結果が表示されない  と言う問題は、LSI C-86 Ver.3.30c 試食版をツールを利用して実行するプログラム共通の問題のようです。  CPad for LSI C-86でも、以下のとおり、同様の問題があり、 COMMAND  プログラムで、この問題を解決しようとしています。 phb1122  でも、以前は、 COMMAND を利用した形跡があります。今は、 PIF ファイルを作成 することで解決しています。  なぜ、このような経緯になったのか詳しく解説していただけませんでしょうか? ******************************* WindowsNT/2000上の CPad for LSI C-86 で、コンパイルはできるが、実行結果が表示されない これは LSI C-86 が16ビットアプリケーションであるために起こる現象です。 解決策は、作成した実行ファイルを実行する前に一度、Windows9xとの互換性のために用意されているcommand.comを実行することで回避できます。 CPad での設定方法は、 [設定]ダイアログ-[高度な設定]ページの[以下の設定を変更する(C)]にチェックをしてから、[実行するコマンド(B)]に %WINDIR%\system32\command.com /c exit > nul と記述して[OK]ボタンをクリックします。 これでNT/2000上でも LSI C-86で作成した実行ファイルの出力を確認できます。 また、この現象が起こらない場合もあるようですが、どういう環境で起こって、どういう環境で起こらないのかははっきりわかっていません。 *********************** C:\phb1122\phoebe.htm ★ NT4/2000/XP で、16 ビットプログラムの実行結果が表示されない場合について Windows NT4/2000/XP で、LSI C-86 試食版を使って 16 ビットプログラムを作成して実行した際に、出力結果が表示されず、空欄になってしまう場合があります。この現象についていろいろ調査してみましたが、NTVDM.EXE の動作に原因がありそうというだけで、それ以上がどうしても分かりません。しかし、強制的に MS-DOS プロンプトを起動させられればうまくいくのではと考え、PIF ファイルを作成し、それを介して実行することで、とりあえず出力結果を表示させることに成功しました。メニューの「ビルド(B)」→「PIF を作成して実行(I)」をチェックすることで設定できます。このメニューは、LSI C-86 試食版をコンパイラに設定しているときのみ有効です。 敬具

  • C言語:forを用いたプログラム

    6時間格闘した結果皆さんに聞くことにさせていただきました; よければ回答、またはヒントを与えてくださるとうれしいです。 自然数nを入力すると,1からnまで出力するプログラムを,for文を用いて作成せよ.ただし,2の倍数の時は数値の右側に*を,3の倍数の時は数値の右側に#を表示させよ ちなみにまだまだ勉強足らない初心者です。