count the number of distinct duplicated characters in a string

Hello guys,

Do you have any idea how to count the number of distinct duplicated characters that appear in a string? For instance in the string "George" I have 2 characters, g and e. I tried with a while loop like

while (s.length()!=0){
if (s[i]==s[i+1]){
count++;
}
}

but this counts how many times a character appeas in the string. I can't find a method that can compare characters within the same string.

Thanks
Put the (lower-case) version of the characters into a std::set, one by one. If the insertion fails then the character is already there.
Do you mean to use a set? Is there a method for strings to compare each character to the next one?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <set>
#include <cctype>
using namespace std;

string duplicates( const string &str )
{
   set<char> distinct, duplicates;
   for ( char c : str )
   {
      c = tolower( c );
      if ( !distinct.insert( c ).second ) duplicates.insert( c );
   }
   return string( duplicates.begin(), duplicates.end() );
}


int main()
{
   string test = "George";
   string dups = duplicates( test );
   cout << "There are " << dups.size() << " duplicates: " << dups << '\n';
}


There are 2 duplicates: eg

also, your [i+1] is safe on a string but would not work on other containers like a vector...
you can't say [last item] == [last item + 1] on most containers because [last item +1] is not valid memory. on a string, there is a hidden extra zero so its safe to tap.


there isnt a string only special snowflake algorithm built in for this, no.

it is less efficient that the set, but you can do something like:
std::transform (tolower or toupper)
followed by
std::sort()
followed by
std::adjacent_find()
which would make good uses of what c++ offers but is a very poor way to solve it. The problem is O(n) and the above is 2N+NlgN or so, much slower... and if you needed the original, it throws a copy in there too (though set is a partial copy, so that evens out).

the set trick is part of an extremely fast algorithm that you do not want to forget. It is useful for a variety of things, mostly sorting and counting and many things similar to counting.
Last edited on
Thank you all. I solved it in a different way

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int dc (string s) {
int i, j, c=0, k=0;
for (i=0; i<s.length(); ++i){
   c=1;
   for (j=i+1; j<s.length(); ++j){
      if (s[i]==s[j]){
        c++;
        s[j] = '0';
    }    
    }
    if (c>1 && s[i]!='0'){
        k++;
    }
}
return k;    
}

Last edited on
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
#include <iostream>
#include <string>

int main()
{
    const int no_of_letters{26};
    int* array = new int[no_of_letters]{0};
    
    std::string word;
    std::cin >> word;
    
    char ch;
    for( int i = 0; i < word.length(); i++ )
    {
        ch = tolower(word[i]);
        array[ch - 'a']++;
    }
      
    for( int i = 0; i < no_of_letters; i++ )
    {
        if(array[i] > 1)
        {
            std::cout << (char)('a' + i);
        }
    }
    
    return 0;
}
Topic archived. No new replies allowed.