我有两个向量结构,一个包含每个的代码和成本,另一个只是包含请求代码和totalCost(待计算(的订单
矢量部分(代码、成本(;
矢量订单(代码,totalCost(//totalCost设置为0;
其中部分向量包含类似('A',10,'B',20(的东西;
其中A和B是零件,10是A的成本,20是B的成本。
订单向量包含A、B、C或A、B的订单。假设我们收到A和B部分的订单。
我们如何根据零件的成本将这两个值相加,并将结果存储在一个新的int中,我们稍后将使用它添加到向量结构订单(totalCost(中。
我试了几个小时,我想我需要使用std::transform,也许还有std::accumulate?只是不知道如何将两者结合在一起。。。
这是我迄今为止所写的:
int totalCost;
for(auto i : customers){
for(auto x : parts){
totalCost = accumulate(i.partsList.begin(), i.partsList.end(), ???);
//then need to store cost for each order for use later
}
我也试过:
void test(){
int cost;
for(unsigned i =0; i < customers.size(); i++){
for(unsigned x=0; x < partsVec.size(); x++){
for(unsigned z=0; z < customers.at(i).partsList.size(); z++){
if(partsVec.at(x).code == customers.at(i).partsList.at(z)){
cost += partsVec.at(x).cost;
customers.at(i).cost= cost;
}
}
}
}
for(auto i : customers){
cout << i.cost<< endl;
}
}
此输出为:
40 //this is correct.
80 //this is incorrect, needs to be 40 as both customers have ordered same parts!
正如你所看到的,这不断地导致有罪,我想不出阻止它的方法
我想做的是,根据零件向量中的信息,获得零件列表中所有零件的总成本。客户向量中有另一个名为partsList的字符向量,然后我可以使用累加或其他算法将每个订单的totalCost更改为从上面获得的值
试试这样的东西:
struct Part
{
char code;
double cost;
Part(char code, double cost)
: code(code), cost(cost)
{
}
};
std::vector<Part> parts;
double costOfPart(char code)
{
for(const Part &part : parts)
{
if (part.code == code)
return part.cost;
}
return 0.0;
}
struct OrderItem
{
char partCode;
size_t quantity;
OrderItem(char partCode, size_t quantity)
: partCode(partCode), quantity(quantity)
{
}
};
struct Order
{
int code;
std::vector<OrderItem> items;
Order(int code)
: code(code)
{
}
void addItem(char partCode, size_t quantity)
{
for (OrderItem &item : items)
{
if (item.partCode == partCode)
{
item.quantity += quantity;
return;
}
}
items.push_back(OrderItem(partCode, quantity));
}
double totalCost() const
{
double total = 0.0;
for (const OrderItem &item : items)
{
total += (costOfPart(item.partCode) * item.quantity);
}
// TOOD: fees, taxes, discounts, etc...
return total;
}
};
std::vector<Order> orders;
double costOfAllOrders()
{
double total = 0.0;
for(const Order &order : orders)
{
total += order.totalCost();
}
return total;
}
double costOfOrder(int orderCode)
{
for(const Order &order : orders)
{
if (order.code == orderCode)
return order.totalCost();
}
return 0.0;
}
...
parts.push_back(Part('A', 10.0));
parts.push_back(Part('B', 20.0));
...
Order order(12345);
order.addItem('A', 1);
orders.push_back(order);
...
double costOfOneOrder = costOfOrder(12345);
double totalCostOfOrders = costOfAllOrders();
...
或者,如果你真的想使用std::accumulate()
,那么你可以这样做:
#include <algorithm>
#include <numeric>
struct Part
{
char code;
double cost;
Part(char code, double cost)
: code(code), cost(cost)
{
}
};
std::vector<Part> parts;
double costOfPart(char code)
{
auto iter = std::find_if(parts.begin(), parts.end(),
[=](Part &part){ return part.code == code; }
);
if (iter != parts.end())
return iter->cost;
return 0.0;
}
struct OrderItem
{
char partCode;
size_t quantity;
OrderItem(char partCode, size_t quantity)
: partCode(partCode), quantity(quantity)
{
}
};
struct Order
{
int code;
std::vector<OrderItem> items;
Order(int code)
: code(code)
{
}
void addItem(char partCode, size_t quantity)
{
auto iter = std::find_if(items.begin(), items.end(),
[=](OrderItem &item){ return item.partCode == partCode; }
);
if (iter != items.end())
iter->quantity += quantity;
else
items.emplace_back(partCode, quantity);
}
double totalCost() const
{
double total = std::accumulate(items.begin(), items.end(), 0.0,
[](double totalSoFar, const OrderItem &item) {
return totalSoFar + (costOfPart(item.partCode) * item.quantity);
}
);
// TOOD: fees, taxes, discounts, etc...
return total;
}
};
std::vector<Order> orders;
double costOfAllOrders()
{
return std::accumulate(orders.begin(), orders.end(), 0.0,
[](double totalSoFar, const Order &order){
return totalSoFar + order.totalCost();
}
);
}
double costOfOrder(int orderCode)
{
auto iter = std::find_if(orders.begin(), orders.end(),
[=](Order &order){ return order.code == orderCode; }
);
if (iter != orders.end())
return iter->totalCost();
return 0.0;
}
...
parts.emplace_back('A', 10.0);
parts.emplace_back('B', 20.0);
...
Order order(12345);
order.addItem('A', 1);
orders.push_back(order);
...
double costOfOneOrder = costOfOrder(12345);
double totalCostOfOrders = costOfAllOrders();
...
更新:根据您添加的代码,您正在循环所有错误。你需要更像这样的东西:
auto partCost = [&](char code) -> int {
for(auto &p : partsVec) {
if (p.code == code)
return p.cost;
}
return 0;
}
int totalCost = 0;
for(auto &c : customers){
totalCost += accumulate(c.partsList.begin(), c.partsList.end(), 0,
[&](int totalSoFar, char code) {
return totalSoFar + partCost(code);
}
);
}
或者,只使用普通循环:
void test(){
int cost = 0;
for(unsigned i = 0; i < customers.size(); i++) {
auto &c = customers[i];
for(unsigned x = 0; x < c.partsList.size(); x++) {
auto partCode = c.partsList[x];
for(unsigned z = 0; z < partsVec.size(); z++) {
auto &p = partsVec[z];
if (p.code == partCode) {
cost += p.cost;
break;
}
}
}
}
cout << cost << endl;
}
只需从零件容器中按成本顺序查找每个零件,然后在累积算法中传递给lambda。我假设,要么顺序表现为一个容器,要么顺序中的每个部分都可以获得并放入一个向量中。
std::accumulate(order.begin(), order.end(), 0, [&parts](const auto & o) {
return std::find(parts.begin(), parts.end(), o).cost();
}
您还可以尝试编写一个"讨厌"的函数对象,该对象将表现为lambda。
class AccumulatorHelper {
public:
vector<Parts>& parts;
AccumulatorHelper(vector<Parts>& p): parts(p) { }
int operator()(const Order& order) {
return std::find(parts.begin(), parts.end(), order.character());
}
};