### Vector same element problem? Hi!

My current task is to make a list of ingredients for a cocktail, stored in a vector. If the ingredient, which the user types in is already in the vector, the counter increases (the ingredient's name and quantity is in a struct). Then, I must count from the total summary of the ingredients and the individual ingredients the percentage of the given ingredient in the "cocktail".

I have problem at counting the individual quantities. It works perfectly when I type in the ingredients in an order where no same ones follow each other. However, if I type the same ingredient after each other, the vector deems it as a new element and adds it to the back. Could you help me how to solve it?

 ``123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899`` ``````#include #include #include struct Ingredient{ std::string name; int quantity; double percentage; }; int main(){ std::string n; int choice = 0, id = 0; std::vectorv; std::vectorlist; std::cout << "Ingredient: "; std::cin >> n; Ingredient f; f.name = n; f.quantity = 1; f.percentage = 100.00; v.push_back(f); list.push_back(n); do{ std::cout << "Ingredient: "; std::cin >> n; if(n == "done"){ break; } for(int i = 0; i < list.size(); i++){ if(list[i] == n){ choice = 1; id = i; break; } } if(choice == 0){ std::cout << n << " is not in the vector!\n"; f.name = n; f.quantity = 1; f.percentage = 100.00; v.push_back(f); list.push_back(n); }else if(choice == 1){ std::cout << n << " is in the vector!\n"; for(int i = 0; i < v.size(); i++){ if(v[i].name == n){ v[i].quantity++; break; } } } }while(n != "done"); for(int i = 0; i < v.size(); i++){ std::cout << "\nName: " << v[i].name << ", quantity: " << v[i].quantity << '\n'; } return 0; }``````
Last edited on ``123456789101112131415161718192021222324252627282930313233343536373839`` ``````#include #include #include struct ingredient { std::string name; int quantity = 1 ; // .. }; // add the ingredient if it is not present, update its quantity otherwise void add_item( std::vector& items, const std::string& name, int qty = 1 ) { // range based loop: https://www.stroustrup.com/C++11FAQ.html#for for( ingredient& ing : items ) { // for each item in the vector if( name == ing.name ) { // note: name is case sensitive // found the ingredient with this name ing.quantity += qty ; // update its quantity return ; // and we are done } } // if we reach here, the ingredient was not found in the vector; add a new item items.push_back( { name, qty } ) ; } int main() { std::vector items ; std::string name ; while( std::cout << "ingredient (enter 'done' to quit): " && std::cin >> name && name != "done" ) add_item( items, name ) ; // default value for quantity is 1 // ... }``````

Using std::map (with the name as the key) would be a good alternative. Consider as C++17:

 ``12345678910111213141516171819202122232425`` ``````#include #include #include #include #include struct Ingredient { std::string name; unsigned quantity {1}; }; int main() { std::vector v; double total {}; for (Ingredient f; (std::cout << "Ingredient (done to exit): ") && (std::cin >> f.name) && (f.name != "done"); ++total) if (const auto fnd {std::find_if(v.begin(), v.end(), [&](const auto& d) {return d.name == f.name; })}; fnd == v.end()) v.push_back(f); else ++fnd->quantity; for (const auto& [nam, qty] : v) std::cout << "\nName: " << nam << ", quantity: " << qty << ", " << std::fixed << std::setprecision(2) << qty / total * 100 << '%'; }``````

 ``` Ingredient (done to exit): qwe Ingredient (done to exit): asd Ingredient (done to exit): zxc Ingredient (done to exit): qwe Ingredient (done to exit): yui Ingredient (done to exit): qwe Ingredient (done to exit): done Name: qwe, quantity: 3, 50.00% Name: asd, quantity: 1, 16.67% Name: zxc, quantity: 1, 16.67% Name: yui, quantity: 1, 16.67% ```

Last edited on
Topic archived. No new replies allowed.