You can use a std::map to keep track of known string counters, eg:
#include <string>
#include <map>
std::string names_str[7] = {"Alex", "Louis", "Alex", "Simon", "Matthew", "Carl", "Simon"};
int names[7];
std::map<std::string, int> counter_map;
int counter = 0;
for (int i = 0; i < 7; ++i)
{
auto iter = counter_map.find(names_str[i]);
if (iter == counter_map.end())
iter = counter_map.insert(std::make_pair(names_str[i], counter++)).first;
names[i] = iter->second;
}
Live Demo
Alternatively, since insert() returns an iterator to an existing keyed element if the key already exists, you can avoid a redundant search via find():
#include <string>
#include <map>
std::string names_str[7] = {"Alex", "Louis", "Alex", "Simon", "Matthew", "Carl", "Simon"};
int names[7];
std::map<std::string, int> counter_map;
int counter = 0;
for (int i = 0; i < 7; ++i)
{
auto ret = counter_map.insert(std::make_pair(names_str[i], counter));
if (ret.second) ++counter;
names[i] = ret.first->second;
}
Live Demo
Either way, since you want to "transform" an array to another array of the same size, this is a good use case for std::transform():
#include <string>
#include <map>
#include <algorithm>
std::string names_str[7] = {"Alex", "Louis", "Alex", "Simon", "Matthew", "Carl", "Simon"};
int names[7];
std::map<std::string, int> counter_map;
int counter = 0;
std::transform(std::begin(names_str), std::end(names_str), std::begin(names),
[&](const std::string &name) {
auto iter = counter_map.find(name);
if (iter == counter_map.end())
iter = counter_map.insert(std::make_pair(name, counter++)).first;
return iter->second;
}
);
Live demo
#include <string>
#include <map>
#include <algorithm>
std::string names_str[7] = {"Alex", "Louis", "Alex", "Simon", "Matthew", "Carl", "Simon"};
int names[7];
std::map<std::string, int> counter_map;
int counter = 0;
std::transform(std::begin(names_str), std::end(names_str), std::begin(names),
[&](const std::string &name) {
auto ret = counter_map.insert(std::make_pair(name, counter));
if (ret.second) ++counter;
return ret.first->second;
}
);
Live Demo
std::setorstd::map. These containers only accept unique keys (strings).counter = 0;every time through the loop it's not going to count very far.