c ++ - 棘手方法 - 需要解决方案 [英] c++ - Tricky Method - need solution
问题描述
对象数组tArray包含买方姓名和购买的数字,每个买方可以在对象数组中多次。我必须在数组中返回五个最大的买家的名字。
The array of objects tArray contains buyer names and the numshares of there purchases, each buyer can be in the array of objects more than once. I have to return in an array the names of the five largest buyers.
我试图与买方名称并行运行两个数组,并且在另一个数组中有总体积。
I attempted to run two arrays in parallel with the buyer name and there total volume in another array.
我的方法一般有缺陷,因为我得到错误的结果,我该如何解决这个问题。
my method in general flawed as i am getting wrong results, how can I solve this problem.
感谢
ntransactions =数组中的事务数
ntransactions = the number of transactions in the array
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;
}
推荐答案
,我从std :: map开始累加值:
Assuming you're allowed to, I'd start by accumulating the values into an 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
。
This will add up the total number of shares for each buyer. Then you want to copy that data to an std::vector, and get the top 5 by number of shares. For the moment, I'm going to assume your struct (with buyername
and numshares
as members) is named 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
看起来像:
For this to work, you'll need a comparison functor named by_shares
that looks something like:
struct by_shares {
bool operator()(transaction const &a, transaction const &b) {
return b.numshares < a.numshares;
}
};
或者,如果你使用的编译器足够支持它,你可以使用lambda的比较显式函数:
Or, if you're using a compiler new enough to support it, you could use a lambda instead of an explicit functor for the comparison:
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点。
Either way, after nth_element completes, your top 5 will be in the first 5 elements of the vector. I've reversed the normal comparison to do this, so it's basically working in descending order. Alternatively, you could use ascending order, but specify the spot 5 from the end of the collection instead of 5 from the beginning.
我应该补充说,还有其他方法做到这一点 - 例如,一个Boost bimap也会做得很好。鉴于这听起来像家庭作业,我的猜测是一个预打包的解决方案像bimap处理几乎整个工作,你可能不会/不会允许(甚至 std :: map
可能被禁止的原因很相同)。
I should add that there are other ways to do this -- for example, a Boost bimap would do the job pretty nicely as well. Given that this sounds like homework, my guess is that a pre-packaged solution like bimap that handles virtually the entire job for you probably would't/won't be allowed (and even std::map
may be prohibited for pretty much the same reason).
这篇关于c ++ - 棘手方法 - 需要解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!