Reputation: 197
I am writing a program to determine whether all characters in a string are unique or not. I am trying to do this using an unordered_set. Here is my code:
#include <iostream>
#include <unordered_set>
#include <string>
using namespace std;
bool uniqueChars(string word) {
unordered_set<char> set;
for (int i = 0; i < word.length(); i++) {
auto character = set.find(word[i]);
// if word[i] is found in set then not all chars are unique
if (character == word[i]) {
return false;
}
//else add word[i] to set
else {
set.insert(word[i]);
}
}
return true;
}
int main() {
string word;
getline(cin, word);
bool result = uniqueChars(word);
return 0;
}
It is giving me this error:
|15|error: no match for 'operator==' (operand types are 'std::__detail::_Node_iterator' and 'char')|
I believe that means that character is not comparable to word[i], but I'm not sure.
How do I make this work?
Upvotes: 2
Views: 1454
Reputation: 30926
*character == word[i]
( This is the way to access the characters but it is not needed and it should be guided by a check whether it points to the past to the last element)
The *charcater is basically referencing the already inserted charcater.
if(character != set1.end() )
return false; // as we are sure that it is not unique character string
You have to dereference it. but in that case you also need to do the whether it return iterator pointing to `set::end``.
By the way there is a really a simple way to do what you are trying to do.
bool uniqueChars(string word) {
unordered_set<char> set1;
for (int i = 0; i < word.length(); i++)
auto character = set1.insert(word[i]);
return set1.size()==word.length();
}
"set" is a key word in c++
Upvotes: 0
Reputation: 137780
Take advantage of the return value of insert
. It tells you whether a duplicate was found during insertion (in which case nothing is inserted).
bool uniqueChars(string word) {
unordered_set<char> set;
for ( char c : word ) {
if ( ! set.insert( c ).second ) {
return false; // set didn't insert c because of a duplicate.
}
}
return true; // No duplicates.
}
However, this isn't as efficient as it might look. unordered_set
is a heap-based hash table and its implementation is fairly heavyweight. A lightweight bit-vector works well for classifying characters.
#include <bitset>
constexpr int char_values = numeric_limits< char >::max()
- numeric_limits< char >::min() + 1;
bool uniqueChars(string word) {
bitset< char_values > set;
for ( char c : word ) {
int value_index = c - numeric_limits< char >::min();
if ( set[ value_index ] ) {
return false;
} else {
set[ value_index ] = true;
}
}
return true; // No duplicates.
}
Upvotes: 1
Reputation: 172894
Note that std::unordered_set::find returns an iterator, not the element. It can't be compared to the element directly.
You could check whether the element was found or not by comparing the iterator with std::unordered_set::end. e.g.
auto character = set.find(word[i]);
// if word[i] is found in set then not all chars are unique
if (character != set.end()) {
return false;
}
//else add word[i] to set
else {
set.insert(word[i]);
}
BTW: Better not to use set
as the name of variable, which is the name of another STL container.
Upvotes: 1