So i have Text.txt where are countries and rivers.So i have to output river and all countries where that current river exists.
Text.txt :
Spanish Taho
France Rhine
Ukrain Dnipro
Germany Rhine
Russia Dnipro
Portugal Taho
Code:
#include <iostream>
#include <map>
#include <string>
#include <fstream>
using namespace std;
int main()
{
map<string, string> country;
ifstream in("Text.txt");
string key;
string river;
while (in >> key >> river)
{
country[key] = river;
}
map<string, string>::iterator it;
map<string, string>::iterator it2;
for (it = country.begin(); it != country.end(); it++) {
cout << it->second << ":" << endl;
for (it2 = country.begin(); it2 != country.end(); ++it2) {
if (it->second == it2->second ) {
cout << "-" << it2->first << endl;
}
}
}
cout << endl;
system("pause");
return 0;
}
Result:
Rhine:
-France
-Germany
Rhine:
-France
-Germany
Taho:
-Portugal
-Spanish
Dnipro:
-Russia
-Ukrain
Taho:
-Portugal
-Spanish
Dnipro:
-Russia
-Ukrain
What I need:
Rhine:
-France
-Germany
Taho:
-Portugal
-Spanish
Dnipro:
-Russia
-Ukrain
how to remove repetitions ?
Some text for escape "
It looks like your post is mostly code; please add some more details." error
Your data structure is not appropriate for the solution.
Try below:
map<string, vector<string>> riverToCountryMap
And while inserting data:
riverToCountryMap[river].push_back(country);
You can use std::multimap for reverse order:
std::map<std::string, std::string> m {
{"Spanish", "Taho"},
{"France", "Rhine"},
{"Ukrain", "Dnipro"},
{"Germany", "Rhine"},
{"Russia", "Dnipro"},
{"Portugal", "Taho"},
};
std::multimap<std::string, std::string> rev;
for (const auto& p : m) {
rev.emplace(p.second, p.first);
}
Demo
You might prefer std::map<std::string, std::vector<std::string>> over std::multimap.
Related
So I have this assignment that I need to read a gigantic text file that includes strings of words separated by spaces into a map. the problem is i need to compare the value of a pair to the key of the pair after and if they match I need to compare the value of the pair that I am currently at to the key of the one after it and so forth. until I form a phrase.there is only one phrase in a very big text file that meet these criteria.
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <map>
int main()
{
std::string line;
std::map <std::string, std::string> mymap;
std::ifstream inFile("shuffled_words.txt");
if (inFile)
{
std::string key = "";
std::string value = "";
while (getline(inFile, line, '\n'))
{
std::istringstream s(line);
while (s >> key>> value || !s.eof()) {
if (s.fail())
{
s.clear();
std::string key,value;
s >> key >> value;
continue;
}
else
{
mymap[key] = value;
}
}
}
}
else
{
std::cout << "file could not be read" << std::endl;
}
inFile.close();
for (auto itr = mymap.begin();
itr != mymap.end(); ++itr) {
std::string _second = itr->second;
for (auto itr = mymap.begin();
itr != mymap.end(); ++itr) {
if (_second == itr->first) {
std::cout << _second << itr->second;
}
}
}
return 0;
}
I have a string like "aabcdba" now I want to store the position of different character's position. I am trying to store using vector and unordered_map. Is there any good approach to store the position of different characters?
void topKFrequent(string s) {
vector<vector<int> >v(123);
//unordered_map<char, vector<int>>m;
for(int i=0;i<s.size();i++) {
v[s[i]].push_back(i);
// m[s[i]].push_back(i);
}
for(int i=0;i<123;i++) {
for(int j=0;j<v[i].size();j++) {
char ch=i;
cout<<ch<<"->"<<v[i][j]<<endl;
}
}
}
if string = "aabcdba", I want the following result:
a->0,1,6;
b->2,5;
c->3;
d->4;
You could use a map<char, vector<unsigned int> >.
#include <iostream>
#include <map>
#include <string>
#include <vector>
using namespace std;
map<char, vector<unsigned int> > storePos(string s)
{
map<char, vector<unsigned int> > charPos;
for(int i=0;i<s.size();i++)
{
auto itr = charPos.find(s[i]);
if(itr != charPos.end())
{
itr->second.push_back(i);
}
else
{
charPos[s[i]] = vector<unsigned int>(1, i);
}
}
return charPos;
}
int main(void)
{
string example = "aabcdba";
auto result = storePos(example);
for(auto itr1 = result.begin(); itr1 != result.end(); itr1 ++)
{
cout << "Letter: " << itr1->first << ", Locations: ";
for(auto itr2 = itr1->second.begin(); itr2 != itr1->second.end();
itr2 ++)
{
cout << *itr2 << " ";
}
cout << endl;
}
}
If you really want to store ordinal positions in the original string sequence, you can do so with either an unordered or ordered map of char to vector, where char is the key, and the vector contains the positions. Using an unordered map will not give you the lexicographical ordering of keys you seem to be seeking, but will nonetheless give you accurate positional vectors.
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
int main()
{
std::string s = "aabcdba";
std::unordered_map<char, std::vector<unsigned int>> mymap;
for (unsigned i=0; i<s.size(); ++i)
mymap[s[i]].push_back(i);
for (auto const& pr : mymap)
{
std::cout << pr.first << "->";
auto it = pr.second.cbegin();
std::cout << *it;
while (++it != pr.second.cend())
std::cout << ',' << *it;
std::cout << ";\n";
}
}
Output
d->4;
c->3;
b->2,5;
a->0,1,6;
If you want lexicographical ordering, the simplest alternative is to simply using a regular ordered map instead. Changing only this:
std::unordered_map<char, std::vector<unsigned int>> mymap;
to this:
std::map<char, std::vector<unsigned int>> mymap;
and including the appropriate header delivers us this for output:
a->0,1,6;
b->2,5;
c->3;
d->4;
which fits exactly what you seem to be looking for.
A possible implementation to store the positions could be using unordered_multimap: (where the key characters can be repeated).
void storePos(string s) {
unordered_multimap<char, int>m;
for(int i=0;i<s.size();i++) {
m.insert(make_pair(s[i],i));
}
}
[EDITED]
But the output may depend on how you use it, or print out the data.
For example, consider the use of a std::multimap instead of std::unordered_map, to populate it you just do:
multimap<char, int>m;
void storePos(string s) {
for(int i=0;i<s.size();i++) {
m.insert(make_pair(s[i],i));
}
}
And to print the data you could have the following method:
void printPos()
{
std::multimap<char,int>::iterator it,itup;
for (it = m.begin(); it != m.end(); )
{
cout << (*it).first << " -> ";
itup = m.upper_bound ((*it).first );
// print range [it,itup):
for (it; it!=itup; ++it)
{
cout << (*it).second << ", ";
}
cout << endl;
}
}
Output:
a -> 0, 1, 6,
b -> 2, 5,
c -> 3,
d -> 4,
Try this!
I have a map like this:
map<string, map<int, int>> collector;
And I have no idea how to insert data in my map. If I had
map<string, int> collector;
with only key-value I would use
collector.insert(pair<string, int>)(name,money));
But what is the way of inserting when we have map in map. I tried to do:
typedef map<int, int> map_;
for(iteration = collector.begin(); iteration != collector.end(); iteration++) {
iteration = collector.find(word);
if(iteration == collector.end()) {
iteration = collector.insert(map_::value_type(num,num).first;
}
}
This way is not working for me.
Here are some ways to insert into your data structure:
#include <iostream> // cout
#include <map>
#include <string>
#include <utility> // make_pair
using namespace std;
int main()
{
using Collector = map<string, map<int, int>>;
Collector collector;
collector["USD"] = Collector::mapped_type{ { 1, 3 }, { 0, 8 } };
collector["EUR"].insert(make_pair(4, 5));
collector["EUR"].insert(make_pair(6, 7));
collector["CHF"][2] = 4;
const Collector::mapped_type jpyIntegers { { 10, 20 }, { 100, 200 } };
collector.insert(make_pair("JPY", jpyIntegers));
collector["MMK"];
for (const auto& a: collector) {
cout << a.first << ": ";
for (const auto& i: a.second) {
cout << "(" << i.first << "|" << i.second << ")";
}
cout << "\n";
}
}
So the file is like this:
tucanos 10
tacobell 5
tucanos 5
pizzahut 15
tucanos 5
pizzahut 2
tucanos 5
Where the string is the restaurant's name and the number is the number of likes it has. I am supposed to find out the sum of number of likes for each restaurant from reading the file but I have no idea how to do it. Does any of you have any hints for me?
first, here is nice function to split std::string into std::vector given a delimiter character:
std::vector<std::string> &split(const std::string &s,
char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
next, we can achieve desired result using this code:
int main(int argc, char** argv) {
std::map<std::string, int> map;
std::ifstream file("file_with_string.txt", std::ifstream::in);
std::string temp;
while (std::getline(file, temp)) {
std::cout << temp << "\n";
std::vector<std::string> tokens;
tokens = split(temp, ' ', tokens);
for (std::vector<std::string>::iterator it = tokens.begin();
it != tokens.end(); it++) {
std::vector<std::string>::iterator it1 = it;
std::map<std::string, int>::iterator mapIt = map.find(*it++);
int number;
std::istringstream(*it) >> number;
if (mapIt != map.end()) {
(mapIt->second) += (number);
} else {
map[*it1] = number;
}
}
}
for (std::map<std::string, int>::iterator it = map.begin();
it != map.end(); it++) {
std::cout << it->first << " " << it->second << "\n";
}
return 0;
}
tucanos 10 tacobell 5 tucanos 5 pizzahut 15 tucanos 5 pizzahut 2 tucanos 5
pizzahut 17
tacobell 5
tucanos 25
RUN SUCCESSFUL (total time: 55ms)
we can make it simpler
std::map<std::string, int> map;
std::ifstream infile("file_with_string.txt",std::ifstream::in);
std::string resturant = "";
int likes = 0;
while(infile >> resturant >> likes ){
map[resturant ] += likes ;
}
but first version gives more insight IMO into iterators, how to traverse std::map, std::vector and how populate map.
Here's some pseudocode:
Open file
For each restaurant-likes pair
Read restaurant-likes pair from file
If first time we've seen a restaurant
Add restaurant to list
Lookup restaurant in list and add likes to total for that restaurant
End For
Close file
Print all restarants and total likes
Use fscanf to parse the input from file and then apply the add operation.
Example
// c:\temp\nameofexecutable.exe < yourtextfile.txt
#include <iostream>
#include <string>
#include <map>
#include <algorithm>
using namespace std;
int main()
{
string resturant;
int likes;
map<string, int> likesCount;
while (cin >> resturant >> likes) {
likesCount[resturant] += likes;
}
for_each(begin(likesCount), end(likesCount), [&](pair<string,int> x){
cout << x.first << " " << x.second << endl;
});
//// using plain for instead of std::for_each
//for (auto i = begin(likesCount); i != end(likesCount); i++) {
// cout << i->first << " " << i->second << endl;
//}
}
maybe can help you:
#include <iostream>
#include <fstream>
#include <map>
#include <string>
#include <iterator>
int
main() {
std::map<std::string, int> count;
std::ifstream infile("cars.dat", std::ios::in);
if (infile == NULL) {
fprintf(stderr, "Failed to open file.\n");
exit(-1);
}
std::string resturant = "";
int likes = 0;
while(infile >> resturant >> likes ){
count[resturant ] += likes ;
}
printf("--------------------each sum-------------------\n");
std::map<std::string, int>::iterator it(count.begin());
for (; it != sum.end(); ) {
printf("%s %d\n", (it->first).c_str(),it->second);
it++;
}
infile.close();
return 0;
}
The result:
--------------------each sum-------------------
pizzahut 17
tacobell 5
tucanos 25
I have a multimap:
std::multimap < string, string >::iterator iter_map;
multimap < string, set<string> > my.map;
Typical output and data structure:
key - value
bird - air
bird - earth
fish - water
lion - earth
lion - water
I would like change the data structure (no only print to) such that that the new data
would be:
bird - air, earth
fish - water
lion - earth, water
In other way, how to eliminate the duplicate keys?
I did this:
int size_mmap = namesMultiMap1.size();
pair<multimap<string,string>::iterator,multimap<string,string>::iterator> ret;
for (int i = 0; i < 1; i++){
cout << " xxx "<< " =>";
ret = namesMultiMap1.equal_range("xxx");
for (nameItr1=ret.first; nameItr1!=ret.second; ++nameItr1)
cout << " " << (*nameItr1).second;
}
In this way I print the values associeted at a key xxx but I print a element at once.
I would like to print all keys and values. I need automated this because the map is big.
If I iterate using a iterator for namesMultiMap1 a print the repeat keys.
Ok, this can be done like follows. Notice, that the type of the result is map<string, set<string> >, not multimap < string, set<string> > as you wanted, cause you don't want duplicated keys in it, so map makes more sense.
#include <map>
#include <set>
#include <string>
#include <iostream>
#include <iterator>
using namespace std;
typedef multimap<string,string> mm;
typedef map<string, set<string> > ms;
ms convert(const mm& m)
{
ms r;
for (mm::const_iterator it = m.begin(); it != m.end(); ++it)
{
set<string>& s(r[it->first]);
s.insert(it->second);
}
return r;
}
int main()
{
mm m;
m.insert(make_pair("john", "kowalski"));
m.insert(make_pair("john", "smiths"));
m.insert(make_pair("mary", "doe"));
m.insert(make_pair("mary", "walker"));
ms s(convert(m));
for (ms::iterator it = s.begin(); it != s.end(); ++it)
{
cout << it->first << ": ";
set<string> &st(it->second);
copy(st.begin(), st.end(), ostream_iterator<string>(cout, ", "));
cout << endl;
}
return 0;
}
This will print:
john: kowalski, smiths,
mary: doe, walker,