0

このコードの目的は、プログラムに渡されたファイルを取得し、ファイル内の各文字の文字頻度を生成することです。上記のコードでは、句読点を削除して小文字に変換しています。

#include<iostream>
#include<string>
#include<fstream>

using namespace std;

int main()
{
    string fileContent = "qr rqh zrxog kdyh eholhyhg lq wkh odvw bhduv ri wkh qlqhwhhqwk fhqwxub wkdw wklv";

    int count[26] =  { 0 }; // an array the size of the alphabet.

    for(int f = 0; f < fileContent.length(); f++) // run til the file end.
    {
            if(fileContent[f] == 32) // to take care of the spaces.
            {
                    f++; // also tried "continue;" and yeild different and also incorrect results.
            }

            if(fileContent[f] >= 48 && fileContent[f] <= 57) //take care of numbers.
            {
                    f++; // tried "continue;"
            }

            count[fileContent[f]]++;

    }

    for(int p = 0; p < 26; p++)
    {
            cout << char(p + 97) << ": " << count[p]  << endl;
    }
return 0;
}

このコードを実行すると、いくつかの正確な頻度と、ひどく不正確な頻度が得られます (他のすべての結果は間違っているように見えますが、数文字後には天文学的に大きな数になります)。これをより良くする方法はありますか?このコードの何が問題になっていますか? リクエストに応じて、明らかに十分に明確ではなかったため、コードをさらに追加しました(ランダムな100を含む文字列を含む)

詳細については、このプログラムは、私が取り組んでいるシーザー シフト デコーダー用です。私は基本的な C++ を使用しており、経験豊富な開発者からのアドバイスをいただければ幸いです。ありがとう!

4

2 に答える 2

0

C スタイルの配列やマジック ナンバーをコードに使用し、どこでもバッファ オーバーフローの危険を冒しています。

あなたのコードをこれと比較してください:

#include <string>
#include <iostream>
#include <map>
using namespace std;

int main()
{
    string fileContent = "qr rqh zrxog kdyh eholhyhg lq wkh odvw bhduv ri wkh qlqhwhhqwk fhqwxub wkdw wklv";
    map<char, int> counts;

    for (char ch : fileContent)
        ++counts[ch];

    for (char ch = 'a'; ch <= 'z'; ++ch)
        cout << ch << ": " << counts[ch] << '\n';
}

または、すべてのマップ コンテンツを印刷するには (発生しなかった文字に 0 を印刷したくない場合)、次を使用できます。

for (auto& item : counts) 
    cout << item.first << ": " << item.second << '\n';

読者がスペースと数字を除外するコードを追加する演習。ヒント: cctypeヘッダーを調べてください。

于 2017-11-03T03:16:31.213 に答える