Unique words

I am trying to read from and excel file and I have a list of names but I want only to print out the names that are unique. ie if sam appears twice I want to discard this name entirely.

string name;
vector<string> hostnameHolder;

int main(){
while (getline(src, name, ','))
{
nameHolder.push_back(name);
sort(nameHolder.begin(), nameHolder.end());
int vSize = nameHolder.size();
name = nameHolder[0];

for (int i = 1; i < vSize; i++)
{
if (name != nameHolder[i])
{
cout << name << ", "
}
}

this is a snippet of my code so far but it is not working how I would like.
Please use code tags. http://www.cplusplus.com/articles/jEywvCM9/
You can edit your post, highlight your code and click the <> button on the right.

1
2
3
4
5
6
7
for (int i = 1; i < vSize - 1; i++) 
{
    if (nameHolder[i] != nameHolder[i + 1]) 
    {
        cout << nameHolder[i] << ", "
    }
}

This won't print the last name though. That's up to you to fix.
Last edited on
A better and an elegant approach is to use std::map. Every time you add a new string, map increments its count index. This is an example for using maps.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>
#include <string>
#include <map>

int main()
{
	std::map<std::string, int> hostnameHolder;
	++hostnameHolder["AAA"];
	++hostnameHolder["BBB"];
	++hostnameHolder["CCC"];
	++hostnameHolder["AAA"];
	++hostnameHolder["BBB"];
	++hostnameHolder["EEE"];
	++hostnameHolder["FFF"];
	++hostnameHolder["GGG"];

	
	std::map<std::string, int>::const_iterator histogram_iter;
   
    for( histogram_iter = hostnameHolder.begin(); histogram_iter != hostnameHolder.end(); ++histogram_iter)
	  if ( histogram_iter->second == 1 )
		  std::cout << "This string \"" << histogram_iter->first << "\" is unique. "  << "\n";
	  
  
	return 0;
}
Last edited on
This container will do what you're talking about.
http://www.cplusplus.com/reference/set/set/

You might also look into unordered_set, which would be quicker to load names into and doesn't care what order they are spit back out in.

Both types have built-in find functions as well.

[EDIT:]
Hmm, you're actually looking for truly unique names in the file, so if sam is mentioned twice you don't want his name even once. This is still easily doable with set, do a kind of boolean subtraction on it.

1
2
3
4
5
6
7
8
9
10
11
12
while(processing names)
{
    pair testval = add name to main set
    if(testval means that name is already in main set)
    {
         add name to a subtraction set
    }
}
for(All names in subtraction set)
{
    remove that name from the main set.
}
Last edited on
Integralfx, your solution will print every word (except the last one), not just the unique words.
I assumed that OP sorted the vector, as they called sort() before the printing out the unique words.
So did I. Consider the sorted vector<string> v= ["A", "A", "B", "B", "C"]:

v[1] != V[2] so it prints v[1]
v[3] != v[4] so it prints v[3]
An approach similar to that of integralfx but respecting the requirement to "discard" non-unique strings, instead of just not repeating them:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

std::istringstream stream("E,B,A,A,C,C,B,C,D,E");

std::istream& src = stream;

int main()
{
    std::vector<std::string> names;

    std::string name;
    while (getline(src, name, ','))
        names.push_back(name);
    
    std::sort(names.begin(), names.end());

    std::size_t i = 0;
    while (i < names.size()-1)
    {
        if (names[i] != names[i + 1])
            std::cout << names[i] << '\n';

        while (i < names.size() - 1 && names[i] == names[i + 1])
            ++i;

        ++i;
    }

    if (i == names.size() - 1) std::cout << names[i] << '\n';
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
			for (name_iter = nameHolder.begin(); name_iter != nameHolder.end(); ++name_iter)
				//if (name_iter->second == 1)

					for (DOB_iter = DOBHolder.begin(); DOB_iter != DOBHolder.end(); ++DOB_iter)
						//if (DOB_iter->second == 1)

		if (Blonde != "yes")
		{
			if (Size >= "12")
			{ 
					cout << name_iter->first << ", " << DOB_iter->first << ", " << Blonde << ", "
					<< Size << ", " << Notes << endl;
			}
		
	}


I have used maps to get unique names and dates of birth. However, now when I apply the other conditions and try to print out the remaining, it shows all unique names and unique DOBs. It doesnt not print out a particular DOB that is blonde for example.
Topic archived. No new replies allowed.