c ++ - 棘手的方法 - 需要解决方案

时间:2013-03-12 13:23:05

标签: c++ arrays string

对象数组tArray包含买方名称和购买的numshares,每个买方可以多次出现在对象数组中。我必须在数组中返回五大买家的名字。

我尝试与买方名称并行运行两个数组,并在另一个数组中运行总量。

我的方法总体上有缺陷,因为我得到了错误的结果,我该如何解决这个问题。

由于

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;
}

3 个答案:

答案 0 :(得分:1)

由于您可以多次购买相同的买家,因此您必须为所有买家存储一个柜台,而不仅仅是其中的5个,因为无法知道您从前5名中删除的买家不应该是其中的一部分前5名(因为tArray中稍后可以将更多项目链接到此买方)。

我建议使用一个stl地图,其中key是买方名称,并且值为项目数。您可以通过迭代tArray来填充它,并汇总同一买家购买的所有商品。 然后,您可以在地图上进行迭代并轻松检索5位顶级买家,因为每位买家只有一个条目。

答案 1 :(得分: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名。目前,我将假设您的结构(buyernamenumshares作为成员)被命名为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;
    }
};

或者,如果您使用足够新的编译器来支持它,您可以使用lambda而不是显式仿函数进行比较:

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,而不是从头开始指定。

我应该补充一点,还有其他方法可以做到这一点 - 例如,Boost bimap也可以很好地完成工作。鉴于这听起来像是家庭作业,我的猜测是,像bimap这样的预先打包的解决方案几乎可以为你处理整个工作可能不会被允许(甚至std::map 也可能

答案 2 :(得分:0)

当外循环开始时,索引i为零,内循环相同。这意味着第一个条件检查tArray[0].buyerName == calcString[0],它与您在循环之前设置的方式相同。这导致calcTotal[0]-2147483648增加并离开内循环。

我不确定,但这似乎不像人们想要的那样。