3

バイナリ ファイルからゼロと 1 の数を数えようとしています。問題は、私が正しくないことです。0 の 1 は no に等しくなります。ゼロの。私がやっていることは、ファイル char を char ごとに読み取ることです。最大 256 文字になる可能性があるため、結果をゼロと 1 の両方の一時配列に格納し、文字が再び発生した場合はそこから取得します。

#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
void func(int* a1 ,int* a2)
{
    for(int i=0;i<256;i++)
    for(int j=0;j<8;j++)
    {
        if( (i & 1) ==1 )
        {
            a1[i]+=1;
        }
        else if( (i & 1) ==0 )
        {
            a2[i]+=1;   
        }
        i>>1;
    }
}
int main()
{
    int zero[256];
    int one[256];
    int tzero[256];
    int tone[256];
    for(int i=0;i<256;i++)
    {
        zero[i]=0;
        one[i]=0;
        tzero[i]=0;
        tone[i]=0;
    }
    func(tone,tzero);
    FILE* input;
    FILE* output;
    output=fopen("ascii.txt","w");
    input=fopen("one.bin","r");
    int c;
    while((c=fgetc(input))!=EOF)
    {
        fprintf(output,"%d\n",c);
        zero[c]+=tzero[c];
        one[c]+=tone[c];
    }
    int zeroes=0;
    int ones=0;
    for(int i=0;i<=255;i++)
    {
        zeroes+=zero[i];
        ones+=one[i];
    }
    cout<<"zeroes:"<<zeroes<<endl;
    cout<<"ones:"<<ones<<endl;
    fclose(input);

    fclose(output);

}
4

2 に答える 2

1

0 と 1 をカウントするループは、次のようにして の値を破棄しますc

c >>= 1;

8 回のシフトがすべて完了すると、cは常に 0 になるため、次のコードでは間違ったカウントがインクリメントされます。

// The value of c is always zero
tzero[c]=z;
tone[c]=o;
one[c]+=tzero[c];
zero[c]+=tzero[c];

cビット カウント ループの前に の値を保存し、ループが終了した後に復元する必要があります。

さらに良いのは、 と の値がファイル内で発生するのを待たずにtzero[]、前もって計算することです。tone[]これにより、メインループの本体が非常に短くきれいになります。

while((c=fgetc(input))!=EOF) {
    one[c] += tzero[c];
    zero[c] += tzero[c];
}
于 2013-09-16T15:29:20.810 に答える
0

目的がファイル内のビットごとのカウント10ビットだけである場合は、ルックアップ テーブルを使用せずに C++ ファイル ストリームを使用することで、作業を大幅に簡素化できます。

#include <iostream>
#include <fstream>

int main(int argc, char** argv)
{
  std::ifstream fpInput("Input.txt");
  unsigned unOnes = 0;
  unsigned unZeros = 0;
  char chTemp;

  chTemp = fpInput.get();
  while (fpInput.good())
  {
    for (unsigned i = 0; i < 8; ++i)
    {
      if (chTemp & 0x1<<i) unOnes++;
      else unZeros++;
    }

    chTemp = fpInput.get();
  }

  fpInput.close();

  std::cout << "Found " << unOnes << " ones." << std::endl;
  std::cout << "Found " << unZeros << " zeros." << std::endl;

  return 0;
}

適切な最適化フラグを渡せば、優れたコンパイラは中間ループを拡張するはずです。

于 2013-09-16T15:47:42.653 に答える