0

オブジェクトの配列tArrayには、購入者の名前と購入のnumsharesが含まれ、各購入者はオブジェクトの配列に複数回存在する可能性があります。私は5人の最大のバイヤーの名前を配列で返さなければなりません。

購入者の名前と並行して2つのアレイを実行しようとしましたが、別のアレイに合計ボリュームがあります。

間違った結果が得られるため、私の方法は一般的に欠陥があります。どうすればこの問題を解決できますか。

ありがとう

ntransactions=配列内のトランザクションの数

string* Analyser::topFiveBuyers()
{
//set size and add buyer names for comparison.
const int sSize = 5;
string *calcString = new string[sSize];
calcString[0] = tArray[0].buyerName;
calcString[1] = tArray[1].buyerName;
calcString[2] = tArray[2].buyerName;
calcString[3] = tArray[3].buyerName;
calcString[4] = tArray[4].buyerName;
int calcTotal[sSize] = {INT_MIN, INT_MIN, INT_MIN, INT_MIN, INT_MIN};

//checks transactions
for (int i = 0; i<nTransactions; i++)
{
    //compares with arrays
    for(int j =0; j<sSize; j++)
    {
        //checks if the same buyer and then increase his total
        if(tArray[i].buyerName == calcString[j])
        {
        calcTotal[j] += tArray[i].numShares;
        break;
        }
            //checks if shares is great then current total then replaces
            if(tArray[i].numShares > calcTotal[j])
            {           
            calcTotal[j] = tArray[i].numShares;
            calcString[j] = tArray[i].buyerName;
            break;
            }   
    }
}
return calcString;
}
4

3 に答える 3

1

同じ購入者が数回いる可能性があるため、上位5人から削除した購入者がこの上位5人の一部であってはならないことを知る方法がないため、5人だけでなく、すべての購入者のカウンターを保存する必要があります(より多くのアイテムが後でこの購入者にリンクされる可能性があるためtArray)。

キーが購入者名であり、アイテムの数を評価するstlマップを使用することをお勧めします。tArray同じ購入者が購入したすべてのアイテムを繰り返して合計することで、それを埋めます。次に、購入者ごとに1つのエントリしかないため、マップ上で反復して上位5人の購入者を簡単に取得できます。

于 2013-03-12T13:51:03.973 に答える
1

許可されていると仮定して、値をstd :: map:に累積することから始めます。

std::map<std::string, int> totals;

for (int i=0; i<ntransactions; i++)
    totals[tarray[i].buyername] += tarray[i].numshares;

これにより、各購入者の株式の総数が合計されます。次に、そのデータをstd :: vectorにコピーし、共有数で上位5つを取得します。今のところ、あなたの構造体(buyernameおよびnumsharesメンバーとして)の名前はであると仮定しますtransaction

std::vector<transaction> top5;

std::copy(totals.begin(), totals.end(), std::back_inserter(top5));

std::nth_element(top5.begin(), top5.begin()+5, top5.end(), by_shares());

by_sharesこれを機能させるには、次のような名前の比較ファンクターが必要です。

struct by_shares { 
    bool operator()(transaction const &a, transaction const &b) { 
        return b.numshares < a.numshares;
    }
};

または、それをサポートするのに十分な新しいコンパイラを使用している場合は、比較のために明示的なファンクタの代わりにラムダを使用できます。

std::nth_element(totals.begin(), totals.end()-5, totals.end(), 
    [](transaction const &a, transaction const &b) { 
        return b.numshares < a.numshares; 
    });

いずれにせよ、nth_elementが完了すると、上位5つがベクトルの最初の5つの要素になります。これを行うために通常の比較を逆にしたので、基本的に降順で機能しています。または、昇順を使用することもできますが、コレクションの最初から5ではなく、コレクションの最後からスポット5を指定します。

これを行うには他の方法があることを付け加えておきます。たとえば、Boostバイマップも非常にうまく機能します。これが宿題のように聞こえることを考えると、事実上すべての仕事を処理するbimapのような事前にパッケージ化されたソリューションは、おそらく許可されない/許可されないでしょう(そしてほぼ同じ理由で禁止されることさえあります)std::map

于 2013-03-12T14:12:46.017 に答える
0

外側のループが開始すると、インデックスiはゼロになり、内側のループでも同じになります。これは、最初の条件がtArray[0].buyerName == calcString[0]、ループの前にそのように設定したときに等しいかどうかをチェックすることを意味します。calcTotal[0]これは、内側のループから増加し-2147483648、内側のループを離れることにつながります。

よくわかりませんが、これは人が望むものではないようです。

于 2013-03-12T13:35:15.220 に答える