-1

すべての素数をファイルに書き込むプログラムを作成したいと思います(人気のあるアルゴリズム「エラトステネスのふるい」があることは知っていますが、自分で作成しようとしています)。まだ値が1であるバイトのすべての複雑さを排除し、それらをファイルに書き込もうとしています。

#include <iostream>
#include <stdlib.h>  
#include <stdio.h>

void afficher_sur_un_ficher (FILE* ficher, int nb_bit);
char el_mask (int x);

int main()
{
    FILE* p_fich;
    char tab[4096], mask, eli_mask;
    int nb_bit = 0, x, f;

    for (int i = 0; i < 4096; i++)
    {
        tab[i] = 0xff;
    }

    for (int i = 0; i < 4096; i++)
    {
        for (mask = 0x01; mask != 0; mask <<= 1)
        {
            if ((tab[i] & mask) != 0)
            {
                x = nb_bit; 
                while ((x > 1) && (x < 16384))
                {
                    eli_mask = el_mask (x);
                    f = x / 8;
                    tab[f] = tab[f] ^ eli_mask;
                    x = x + nb_bit;
                }
                afficher_sur_un_ficher (p_fich, nb_bit);
            }
            nb_bit++;
        }
    }
    system ("PAUSE");
    return 0;
}

void afficher_sur_un_ficher (FILE* ficher, int nb_bit)
{
    ficher = fopen ("res.txt", "a+");
    fprintf (ficher, "%d \t", nb_bit);
    int static z;
    z = z + 1;
    if (z % 10 == 0)
        fprintf (ficher, "\n");
    fclose (ficher);
}

char el_mask (int x)
{
    x = x % 8;
    switch (x)
    {
        case 0:
            x = 0b00000001;
        break;
        case 1:
            x = 0b00000010;
        break;
        case 2:
            x = 0b00000100;
        break;
        case 3:
            x = 0b00001000;
        break;
        case 4:
            x = 0b00010000;
        break;
        case 5 :
            x = 0b00100000;
        break;
        case 6 :
            x = 0b01000000;
        break;
        case 7:
            x = 0b10000000;
        break;
    }
    return x;
}
4

3 に答える 3

5

非素数を示すビットをクリアしようとしているループに問題があるようです。

while (( x > 1 )&&(x < 16384))
{
    tab[i] = tab[i] ^ mask ;
    x = x * 2 ;
}

このiループでは変化しないため、基本的に、インクリメント中に同じビットのオンとオフを切り替えますx。インデックスをに固定するだけでなくtab[]、操作をxor(^)から無条件にビットをクリアするものに変更することもできます。ビットがクリアされたら、別の要素でそのビットを再度処理して'リセットする必要はありません。 'ビット。のその他の要素のiの倍数が同じビットオフセットにない可能性があるため、単純な増分ではないことに注意してください(実際、の単一の要素にはの倍数が複数含まれている可能性があります)。xtabtab[]x

x = x * 2;その問題を修正したとしても、ループはその倍数をウォークスルーしないため、期待どおりに動作しない可能性があると思います。つまり、x一部の非素数をスキップすることになります。

「エラトステネスのふるい」がどのように機能するかについてのいくつかの研究が役立つかもしれません。

于 2010-04-14T00:13:35.950 に答える
1

多分私は何かが欠けているかもしれませんが、これはただ不安定に思えます.私は一般的な素数アルゴリズムをすぐには覚えていませんが、例えば、

(excerpts) tab[i] = 0xff ; mask = 0x01 ;

for (int j = 0 ; j < 8 ; j++) { if ((tab[i] & mask) != 0 ) mask = mask<<1 ;

これは、常に 8 回実行されることを意味します。なぜ「&」でチェックする必要があるのでしょうか。

もう一つ、

x = nb_bit ; while (( x > 1 )&&(x < 16384)) { tab[i] = tab[i] ^ mask ; x = x * 2 ; }

これは、反復ごとにビットをフリップフロップするだけです。それはあなたが望むものですか?

最後に、何をするつもりなのかわからないので、オブジェクトのビット長に注意してください。あなたはフリップフロップするかもしれません

0000 0000 1111 1111 ^ 0000 0001

また

1111 1111 1111 1111 ^ 0000 00001

あなたが何をしようとしているのかよくわからないので、これが関連しているのかどうかはわかりません。

編集(ハムザのコメント後):

はい。このループが行うことは次のとおりです - compare/'and'

1111 1111 1111 1111

      0000 0001
      0000 0010
      0000 0100,

そして、それは常に当てはまります。ここで何をしたいのかわかりませんが、これは怪しいようです (しばらくの間インターネットがない状態で場所を変更しますが、gl. :))。

于 2010-04-14T00:32:05.347 に答える
1

メイン関数を少し単純化できます。

int main (int argc, char** argv) {
    FILE* p_fich;
    char tab[4096] , mask;
    int nb_bit = 0 , x;

    memset(tab, 0xFF, 4096);
    for (int i = 0; i < 4096; i++) {
        for (mask = 0x01; mask != 0; mask <<= 1) {
            if ((tab[i] & mask) != 0) {
                for (x = nb_bit; (x > 1) && (x < 0x4000), x<<=1)
                    tab[i] ^= mask;
                afficher_sur_un_ficher (p_fich, nb_bit);
            }
            nb_bit++;
        }
    }
    system ("PAUSE");
    return 0;
}

さて、あなたの質問に答えるために:あなたの関数はあなたがそれに渡したものを出力し、その関数はtrueのafficher_sur_un_ficherループ反復ごとに呼び出されます。((tab[i] & mask) != 0)すべてのtab[i]バイトを0xFFに初期化するため、特定のビットの組み合わせをマスクすると、常にそのifステートメントが評価されtrueます。の値を変更していますがtab[i]、一度変更すると、そのビットを使用しなくなるため、ifステートメントが常に取得されるという事実は変わりません。これが、すべてのエントリがログに記録されている理由です。

編集: 出力の決定または出力する値に影響しないすべてのコードを単純化すると、次のようになります。

memset(tab, 0xFF, 4096);
for (int i = 0; i < 4096; i++) {
    for (mask = 0x01; mask != 0; mask <<= 1) {
        afficher_sur_un_ficher (p_fich, nb_bit);
        nb_bit++;
    }
}

ご覧のとおり、このコードは整数 (0 ~ (4096*8)-1) のインクリメント シーケンスを出力し、配列および および の特定の値から完全に独立していtabます。アルゴリズムの実装に何かが欠けていると思います。実装しようとしているアルゴリズムの説明へのリンクはありますか? それともあなたが開発したアルゴリズムですか?(申し訳ありませんが、質問に追加したアルゴリズムの説明がわかりませんでした)imask

于 2010-04-14T00:41:58.080 に答える