0

次のような形式のファイルのデータを読み取りたい:

Point1, [3, 4]

区切り文字 '[' ']' と ',' を使用しており、それらを ' ' (空白) に置き換えています。私のコードは問題なく動作しています。しかし、問題は、Point1, [3, 4]一度出現すると一意になり、テキストファイルに同じデータが存在する場合は二度と出現しないようにすることです。

ここに私が持っているものがあります:

string line, name;
char filename[50];
int x,y;

cout << "Please enter filename : ";
cin >> filename;

ifstream myfile(filename);
if (myfile.is_open()) {
    while ( myfile.good() ) {
        getline(myfile, line);

        for (unsigned int i = 0; i < line.size(); ++i) {
            if (line[i] == '[' || line[i] == ']' || line[i] == ',') {
                line[i] = ' ';
            }
            istringstream in(line);
            in >> name >> x >> y;                                  
        }
        cout <<name <<endl;

        if (name=="Point") {
            p.push_back(Point(x,y));         
        }                          
        count++;
    }    
    myfile.close();
    cout << count;
}
else cout<< "Unable to open file";

どうすればいいですか?この後追加してみましたif(name=="Point")

for (int j=0; j<p.size(); j++) {
    if(p.getX != x && p.getY) != y) {
        p.push_back(Point(x,y))
    }
}

...しかし、データがベクターに格納されていないため、これは正しく機能していません。

誰でも助けることができますか?

4

2 に答える 2

4

データを に保存する代わりに、 に保存vectorsできますsetsPointsセットには一意の値のみが含まれているため、の一意性をチェックする必要はありませんset。 がそれを管理します。

を定義する代わりに、 を定義するvector<Point>必要があり、 を使用してベクトルに点を追加する代わりに、それが である場合は使用するset<Point>必要があります。p.push_backp.insertset

setドキュメントはこちらで確認できます。

于 2012-11-11T11:38:15.043 に答える
0

データ ストアを に保持したいと仮定するとstd::vector<Point>、対応するポイントが既に存在しないことを確認できます。等値演算子が定義されていると仮定すると、次のように簡単です。

if (p.end() == std::find(p.begin(), p.end(), Point(x, y))) {
    p.push_back(Point(x, y));
}

タイプに等値演算子がなく、取得すべきでない場合は、代わりにPoint関数オブジェクトを一緒に使用できます。たとえば、次のようになります。find_if()

if (p.end() == std::find_if(p.begin(), p.end(),
                      [=](Point const& v) { return x == v.x && y == v.y; })) {
    ...

ループを他の操作から分離する必要があります。ポイントが既に存在するかどうかを確認するために提案するループは、基本的std::find()に、各反復で新しいポイントを挿入することを除いて何をするかです! まず、既存のすべてのポイントを調べて、それがどこかに存在するかどうかを確認します。そうでない場合にのみ、新しいポイントを挿入します。

文字列内の文字を置き換えるときに同様の間違いを犯したことに注意してください。各文字をチェックした後に文字列をデコードしようとします。これはセマンティックの問題ではありませんが、パフォーマンス上の大きな問題です。ループ内の文字を置き換える必要があり、そのループの、文字列を一度だけデコードする必要があります。もちろん、文字列をデコードするときは、入力操作が成功したかどうかを常に判断する必要があるため、フォーマットが問題ないかどうかを確認する必要があります。つまり、ループが文字を置き換えた後、次のようなものが必要です。

std::istringstream in(line);
if (in >> name >> x >> y) {
    // now process the data
}

...または、あなたが私のようで、一時的にしか存在しないものに名前を付けるのが好きでない場合:

if (std::istringstream(line) >> std::ws >> name >> x >> y) {

別の注意として、ストリームをチェックすることgood()は一般的に間違ったことです。ストリームは、ある時点で EOF を検出したことを除いて、完全に良好な状態にある可能性があるためstd::ios_base::eofbitです。さらに重要なことは、入力操作の前ではなく、操作のにチェックする必要があることです。つまり、最初のループは次のように開始する必要があります。

while (std::getline(myFile, line)) {
    ...
于 2012-11-11T12:21:30.760 に答える