忍者ブログ

神戸電子専門学校ゲームソフト学科の生徒が運営するGESのブログです。

   

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

素数を数える

はじめまして、Sと申します。以後お見知り置きを。
初めてGESブログに記事投下させて頂きますので、分かり難い部分とかあったらごめんなさい。
私の記事の方向性は殆どが「誰得・気まぐれ」ですので息抜き程度に読んでいただけると幸いです。
 
今回取り上げるのは”素数を表示する”アルゴリズムです。
 
 

拍手[3回]



事前知識として、皆さんは素数がどのような数値か知っていますか?
簡単に説明しますと、「1とその数値以外では割り切れる正の整数値が存在しない正の整数」です。

例えば7が素数かどうかを知りたい場合、2~6の数字で割っていき、全てで割り切れなかったら、7は素数となります。

ではそれをC言語のプログラムで表現してみましょう。
範囲は1~100で出しています。
-------------------------------------------------
int i;
for(i = 1; i < 100; i++){

int judge = 0; /*0:素数 1:素数ではない*/

int j;
/*調べたい数値より小さい値でループ*/
for(j = 1; j < i; j++){
  if( i % j == 0){
   /*割り切れたら素数じゃないからループを抜ける*/
   judge = 1;
   break;
  }
}

/*素数判定*/
if( judge == 0){
  printf("%d"は素数\n, i);
}
}
-------------------------------------------------

簡単に書くとこんな感じですね。

上記の例は試し割りと呼ばれるアルゴリズムです。
これも正しいアプローチなのですが、上記のコードですといくつか無駄な計算があります。
ですので個人的に計算の無駄を省いてみたコードを考えてみました。
割り算回数を減らすことに意識をしたのでその他の部分は最適化していません。
ソースが難しくて解らないって場合は是非ラボⅠに来て下さい!
先輩たちはみんなからの質問を待っています!


皆さんがこれからゲームを制作していくにあたって「これってどうやったら出来るんだろう」とか「他にも方法無いかなぁ」とか考えるときに、全く別な経験からアイディアが出ることがあります。
このソースを思いついたのも高校の数学の授業での知識が有ったからでした。
解決の種が何処に潜んでいるのかはわかりません。
なので余裕のある時に苦手なことでも好きな事でも、とにかく色んなことにチャレンジしてみて下さい。


-----------------------------------------------------------------------
#include <Windows.h>
#include <iostream>
#include <vector>


//最短手順で素数を数えるアルゴリズムテスト

int main(void){

int limit(1);

std::cout << "自然数を入力してね☆ " << std::endl;
std::cin >> limit;

if( limit < 2 ){
  std::cout << "値にエラーがありますので終了します" << std::endl;
  return 0;
}


//素数を格納する配列
std::vector<int> prime_number;

//最初に2を格納する
prime_number.push_back(2);

//今回はとりあえず1~100までの素数を数える
for(int i(3); i < limit; i += 2){

  //最後を指すイテレータと、操作用イテレータを用意
  std::vector<int>::iterator it(prime_number.begin() );
  std::vector<int>::const_iterator endit(prime_number.end() );

  //現在配列に格納されている素数リストで割り算を行なって結果を見る
  for( ; endit != it; ){

   //割り算で割り切れない場合は次の要素を試す
   if( i % (*it) != 0){
    it++;
    continue;
   }
   //割り切れたらループを抜ける
   break;
  }
 
  //ループを抜けた時点でイテレータの値を比較する

  //操作用イテレータの値が 最後を指すイテレータを指している→ループ完走→素数として追加
  //同一の値になっていない→ループを途中で抜けた→素数ではない
  if( endit == it){
   prime_number.push_back(i);
  }
}


/*結果表示*/
//最後を指すイテレータと、操作用イテレータを用意
std::vector<int>::iterator it(prime_number.begin() );
std::vector<int>::const_iterator endit(prime_number.end() );

for( ; endit != it; it++){
  std::cout << (*it) << std::endl;
}


//終了メッセージ
std::cout << "エスケープキーを押してね" << std::endl;

while(1){
  if(GetAsyncKeyState(VK_ESCAPE) ){
   break;
  }
}

return 0;
}
-----------------------------------------------------------------------
PR

COMMENT

NAME
TITLE
MAIL(非公開)
URL
EMOJI
Vodafone絵文字 i-mode絵文字 Ezweb絵文字
COMMENT
PASS(コメント編集に必須です)
SECRET
管理人のみ閲覧できます

ブログ内検索

最新コメント

[01/29 人面犬]
[10/01 8ch]
[09/12 uncle]
[09/10 某卒業生]
[06/07 uncle]

カレンダー

10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

テスト

Copyright ©  -- GESブログ --  All Rights Reserved
Design by CriCri / Photo by Geralt / powered by NINJA TOOLS / 忍者ブログ / [PR]