0

C++ クラスの割り当てに取り組んでおり、ifstream を使用して while ループでベクトルにデータを渡すのに問題があります。

これは私がそれをやった方法であり、うまくいきますが、データファイルが100未満の整数であることに依存しています:

void Frequency()
{
    ifstream frequency("test.dat");
    if (! frequency)
    {
        cout << "**Error opening File**";
    }
    else
    {
        int data;
        vector <int> numbers(101, 0);
        while(frequency >> data)
        {
            numbers[data-1] += 1;
        }
        for(int i = 100; i >= 1; i--) //
        {
            if (numbers[i] != 0)
            {
                cout << setw(3) << i+1 <<": " << numbers[i] << endl;
            }
        }
    }
}

特定の数値の頻度を降順で返します。

これは、コーディングしているというよりも、自分のやり方を打ち破っているように感じますが (私のインストラクターは「これが簡単な方法です!」と主張していますが、私は簡単ではなく、正しくしたいのです。私は次のようにしていました:

void Frequency()
{
    ifstream frequency("test.dat");
    if (! frequency)
    {
        cout << "**Error opening File**";
    }
    else
    {
        int size = 0;
        int x; //actually a useless variable, only exists so the program can iterate to find the size
        while (frequency >> x) //gives us the size of the data file
        {
            size++;
        }
        vector <int> numbers(size, 0);
        int data;
        int a = 0; 
        while (frequency >> data) //inputs the data into the vector
        {
            numbers[a] = data;
            a++;
        }
        for (int a = 0; a < size; a++)
        {
            frequency >> numbers[a];
        }
        for(int i = 0; i < size; i++) //displays each subvector and it's value (for testing)
        {
            cout << "numbers[" << i << "]: " << numbers[i] << endl;
        }
    }
}

しかし、すべてのベクトルが 0 として返されます。データが正しく渡されない理由がわかる人はいますか?

これは参照用に渡しているデータ ファイルです。75 85 90 100
60 90 100 85 75 35 60 90 100 90 90 90 60 50 70 85 75 90 90 70

編集:いくつかのコメントされたものを修正しました。MAPでやってみます。今私を混乱させている最大のこと(がやったように、データファイルがベクトルに渡されない理由です)

4

1 に答える 1

2

ファイルに個別の値がいくつあるかわからないため、2 つのオプションがあります。resize必要に応じてベクトルを使用するか、map. 後者は、この問題に取り組む最も簡単な方法です。

std::map<unsigned, unsigned> numbers;

while(frequency >> data)
{
    numbers[data]++;
}

数値をもう一度繰り返したい場合は、現在のアプローチを使用できます。ただし、これにより、追加のエントリがマップに追加されます ( を参照std::map::operator[])。ただし、iteratorsマップに追加された値のみを表示するために使用できます。

for(
    std::map<unsigned, unsigned>::iterator it = numbers.begin(); 
    it != numbers.end();
    it++
){    
    cout << setw(3) << it->first <<": " << it->second << endl;
}

C++11 の使用が許可されている場合は、range-for-loops を使用するとさらに簡単になります。

for(auto entry : numbers){
{    
    cout << setw(3) << entry.first <<": " << entry.second << endl;
}
于 2013-03-28T20:21:11.027 に答える