1

私は自分でC++を学んでいるので、いくつかの領域に空白のページがあります。コンテナでのいくつかの操作、さまざまな操作の名前など。したがって、この問題を解決するために私を助けてください。(また、適切なコンテナーとそれらを処理する方法を選択するのに役立つ優れたリソースに送っていただければ幸いです。実際の実装例は、この方法で簡単に入手できるため、非常に役立ちます。)

これは私の最初の「本物の」プログラムです。私はPHPで作成しましたが、学習しながらC ++に書き直しています(そして、もっと難しいと言えます)。

つまり、ファイルが読み取られ、対応する要素(人の名前、アイテムの名前、アイテムの金額)を含む3つの異なるベクトルが作成されます。したがって、たとえば(値を割り当てる方法ではなく、内容を説明するためだけに):

vector<string> vectorOfNames = {"Adam", "Eva", "Adam", "Adam", "Bruce"};
vector<string> vectorOfItems = {"Apple", "Apple", "Orange", "Pear", "Melon"};
vector<int> vectorOfAmount = {1, 9, 2, 4, 1};

今、私はそれを(人とアイテムで)表現し、それらのベクトルを(量で)数えたいと思います。次のようなものを印刷するには:

All persons:
Adam
Eva
Bruce

All items:
Apple - 10
Orange - 2
Pear - 4
Melon - 1

Adam have:
Apple - 1
Orange - 2
Pear - 4

Eva have:
Apple - 9

Bruce have:
Melon - 1

PHPでは、* array_keys(array_flip())*を使用して一意の名前とアイテムを取得しました。C ++では、次のようなものが見つかりました。

vector< string >::iterator r , w ;

set< string > tmpset ;

for( r = vectorOfNames.begin() , w = vectorOfNames.begin() ; r != vectorOfNames.end() ; ++r )
{
    if( tmpset.insert( *r ).second )
    {
        *w++ = *r ;
    }
}

vectorOfNames.erase( w , vectorOfNames.end() );

それはうまく機能しますが、問題は元のvectorOfNamesを変更することです。これを適用する前に、このベクトルを新しいベクトルにコピーする必要がありますか、それとも別のアプローチがありますか?

PHPで必要な残りの処理については、foreachステートメントとifステートメントを使用しました。C ++でさまざまなアプローチを試しましたが、何も機能しません。私は完全に迷子になっています...また、Boost Libraryにはいくつかの機能があることも知っていますが、当面はそこに行きたくないので、最初に基本を学ぶことを好みます。

一方、この処理を簡単にするために、マップなどの他のコンテナを使用する必要がありますか?

それで、あなたが私が何を意味するかをまだ知っていて、あなたが眠りに落ちなかったならば、正しい方向に私を押してください;)

4

2 に答える 2

3

最初のステップ、つまり、Iですべての一意の名前を取得するstd::vector<std::string>には、おそらく次のようにします。

std::vector<std::string> tmp(original);
std::sort(tmp.begin(), tmp.end());
std::unique_copy(tmp.begin(), tmp.end(),
                 std::ostream_iterator<std::string>(std::cout, "\n"));

別の解決策では、補助を使用できますstd::set<std::string>が、名前をソートされた順序で出力しません。

std::set<std::string> mark;
std::copy_if(original.begin(), original.end(),
             [&](std::string const& value) { return mark.insert(value); });

(C ++ 2011の機能を利用)

他の操作は、C++アルゴリズムの動作方法に直接簡単にマッピングすることはできません。これらに対処するために、私はおそらく別のデータレイアウトを使用します。たとえば、std::vector<std::tuple<std::string, std::string, int> >3つの別々のベクトルではなくデータを格納します。

于 2012-10-02T19:03:02.043 に答える
0

これは、元のアプローチに近いままです。

vector< string > vs;
vs.resize(vectorOfNames.size()); // more efficient if we already know the size

set< string > tmpset ;

vector< string >::const_iterator r;
for( r = vectorOfNames.begin() ; r != vectorOfNames.end() ; ++r )
{
    if( tmpset.insert( *r ).second )
    {
        vs.push_back(*r);
    }
}

ただし、新しい名前を格納するために補助ベクトルを使用するため、元のベクトルを変更する必要はありません。ベクトルを実際に変更しないことを保証するために、このアプローチではイテレーターではなくconst_iteratorを使用します。

于 2012-10-02T19:42:45.800 に答える