如何根据来自另一个向量的信息将向量中的元素添加在一起

Posted

技术标签:

【中文标题】如何根据来自另一个向量的信息将向量中的元素添加在一起【英文标题】:How to add elements in vector together based on info from another vector 【发布时间】:2020-04-15 23:31:53 【问题描述】:

我有两个向量结构,一个包含每个的代码和成本,另一个只是包含请求代码和总成本(待计算)的订单

矢量部分(代码、成本);

矢量订单(代码,总成本); //totalCost 设置为 0;

parts 向量包含类似 ('A', 10, 'B', 20);

其中 A 和 B 是零件,A 的成本为 10,B 的成本为 20。

并且订单向量包含诸如 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 中所有零件的总成本。客户向量中有另一个字符向量称为partsList,然后我可以将每个订单的totalCost更改为使用累积或其他算法从上面获得的值

【问题讨论】:

请提供所有变量定义 让我们看看你一直在做什么。据我们所知,您在第 42 行有一个小错误,可以在几秒钟内消除。 【参考方案1】:

试试这样的:

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;

【讨论】:

谢谢你,我会去删除这个问题,并用我自己的代码重新发布以使其“足够详细”。 @Hugs 你不需要删除这个问题。只需对其进行编辑以添加更多细节,然后就可以重新打开它。 @Hugs 我想你的意思是“编辑过的问题”。我已经更新了我的答案。 @Hugs 阅读了 cppreference.com 文档中的 lambda expressions 和 std::accumulate() 算法的 op 参数。【参考方案2】:

只需从零件容器中按顺序查找每个零件的成本,然后在累积算法中将其传递给 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());
    
;

【讨论】:

感谢您的回复!我是新手,请问没有 lambda 怎么办? 您可以编写一个行为类似于 lambda 的函数对象。但我强烈建议在日常代码中使用 lambda,前提是您使用的版本低于 C++03 或纯 C。 不太行,后o不能得到实际成本:( 我只是试图传达一个结构,在该结构中,可以找到带有订单值字符的累积调用。如果你不能让 character() out of Order 或 cost() out of Part,你可以考虑在相应的类中改变 interface。

以上是关于如何根据来自另一个向量的信息将向量中的元素添加在一起的主要内容,如果未能解决你的问题,请参考以下文章

如何将唯一指针从一个向量移动到另一个唯一指针向量? [关闭]

将向量的每个元素与 R 中的另一个向量组合

如何检查向量的所有元素是不是在 Eigen c++ 中的另一个向量中?

将向量的特定元素广播到另一个向量

如何根据不同 R 生态系统中的另一个向量重写代码,将函数应用于行子集?

如何根据索引的`vector<int>`使用来自另一个`Eigen::VectorXd`向量的值初始化`Eigen::VectorXd`