Reputation: 103
LE: In case it has any relevance i am using CLion. The program doesn't print anything.
I need to process a vector that contains vectors of string in the form of name card_type
and display all cards in alphabetical order and the number of instances for each one. Output should look something like:
a_card 1
mastercard 4
visa 3
The code i have so far, that exits with error Process finished with exit code -1073741819
. What is the issue?
#include <iostream>
#include <vector>
#include <string>
void stats(const std::vector<std::vector<std::string>>& vec) {
std::vector<std::pair<std::string, int>> orderedCards;
for (const auto& client : vec){ //scan database for cards and make ordered vector of pairs
if (orderedCards.empty()){ //insert first pair to empty vector
orderedCards.push_back(std::make_pair(client[1],1));
}else{ //for each new client scan vector and add new client/increment counter
for (auto pair = orderedCards.begin(); pair != orderedCards.end(); ++pair){
if (client[1][0] < pair->first[0]){ //compare first letter of new client and existing client
orderedCards.insert(pair, std::make_pair(client[1], 1));// if its smaller, insert in front
break;// break iteration and go for next client
} else if (client[1] == pair->first){ //if theyre the same, increment counter
pair->second+=1;
break;
} else if (pair+1 == orderedCards.end()) //if end is reached, there was no existing client thus add new one with high letter
orderedCards.push_back(std::make_pair(client[1], 1));
}
}
}
for (const auto& count : orderedCards)
std::cout<<count.first<<" "<<count.second<<std::endl; //print on each line card and counter
}
std::vector<std::vector<std::string>> dataBase;
int main()
{
dataBase={{"name", "bankcard"},{"name", "visa"},{"name", "bankcard"},{"name", "mastercard"},{"name", "bankcard"},{"name", "visa"}};
stats(dataBase);
return 0;
}
Upvotes: 3
Views: 108
Reputation: 1276
@xampierre here a simpler function without using std::sort and the algorithm lib
void stats(const std::vector<std::vector<std::string>>& vec)
{
std::map<std::string, int> orderedCards;
for(auto & client : vec)
{
auto it = orderedCards.insert(std::make_pair(client[1],1));
if (!it.second) // this means that the key was already in the map
it.first->second+=1;
}
for (const auto& count : orderedCards)
std::cout<<count.first<<" "<<count.second<<std::endl; //print on each line card and counter
}
Upvotes: 2
Reputation: 103
Thanks to @yaodav i switched from iterators to a map and sorting alg. Updated code with explanations:
#include <iostream>
#include <vector>
#include <string>
bool compare(const std::pair<std::string , int>& pair1, const std::pair<std::string , int>& pair2){
return pair1.first[0] < pair2.first[0];
}
void stats(const std::vector<std::vector<std::string>>& vec) {
std::map<std::string, int> map;
for (const auto& client : vec){ //scan database for cards and make map
auto ret = map.insert({client[1], 1});// insert new key:value pair
if (!ret.second) // this means that the key was already in the map
ret.first->second+=1; // dereferance pointer to key to access value and +=1
}
std::vector<std::pair<std::string, int>> orderedCards(map.begin(), map.end()); // make vector of pairs (key, value)
std::sort(orderedCards.begin(), orderedCards.end(), compare); // sort vector according to defined compare
for (const auto& count : orderedCards)
std::cout<<count.first<<" "<<count.second<<std::endl;
}
std::vector<std::vector<std::string>> dataBase;
int main()
{
dataBase={{"name", "bankcard"},{"name", "visa"},{"name", "bankcard"},{"name", "mastercard"},{"name", "bankcard"},{"name", "visa"}};
stats(dataBase);
Upvotes: 0