Best way to Find amount of chars existing in both strings

I want to know how many chars exists in both strings.
1
2
3
4
5
getPoints("hey", "hai")
would give: 1 point

getPoints("hi", "hai")
would give: 2 points


It's simple but I really want the fastest way of doing it (without having to sort the strings in advance).

Got any ideas?
Last edited on
My idea is that you could drop the characters into a 24 fields long array (each field would represent a letter. All fields >= 2 would flag shared characters.

But I believe that would only be worth if there are pretty long strings.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* Tests how many ASCII-coded chars two strings
 * do share. The code is still untested.
 */
int getPoints( const std::string a, const std::string b)
{
    static std::array<int,128> arr;
    for( val : arr ) { val = 0; }
    
    for( auto ch : a ) { if( arr[ch] == 0) ++ arr[ch]; }
    for( auto ch : b ) { if( arr[ch] == 1) ++ arr[ch]; }
    
    int points = 0;
    for( auto val : arr ) {
       if( val == 2 ) { ++ points; }
    }
    return points;
}


*edited*
Here the revised code, with influences from lastchance's code below. It regards now upper- and lower cases.
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
35
36
37
38
39
40
#include <array>
#include <iostream>
#include <string>

int getPoints( std::string & a, std::string & b)
{
    static std::array<int,128> arr;
    for( int & val : arr ) { val = 0; }
    
    for( char & ch : a)
    {
        ch = std::tolower( ch );
        if( arr[ch] == 0) { ++ arr[ch]; }
    }
    for( char & ch : b)
    {
        ch = std::tolower( ch );
        if( arr[ch] == 1) { ++ arr[ch]; }
    }
    
    int points = 0;
    for( int val : arr) { if( val == 2) ++ points; }
    return points;
}

int main()
{
    using namespace std;
    
    while( true ) // Exit with Ctrl+c or Ctrl+z (Windows)
    {
        string a, b;
        
        cout << "Enter string a: ";  getline( cin, a);
        cout << "Enter string b: ";  getline( cin, b);
        
        cout << "Number of common characters = "
             << getPoints( a, b) << '\n';
    }
}
Last edited on
You'd also have to consider how to handle (a) white-space, (b) punctuations and (c) case sensitivity

http://stackoverflow.com/questions/21657544/finding-common-characters-in-two-strings
Probably overkill, but you could put each string into its own set<char>, observing case sensitivity at the same time. Then merge the sets. The difference between the sum of sizes in the original sets and the size of the final one will be the number in common (the number rejected in the merge).

Note: this refers to distinct characters - not duplicates. So, just 'l' (once) and 'o' in the example below.

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
#include <iostream>
#include <set>
#include <string>
#include <cctype>
using namespace std;


void lower( string &s ) { for ( char &c : s ) c = tolower( c ); }


int numberInCommon( string A, string B )
{
   lower( A );
   lower( B );

   set<char> setA( A.begin(), A.end() );
   set<char> setB( B.begin(), B.end() );

   int sizeA = setA.size();
   setA.insert( B.begin(), B.end() );
   return sizeA + setB.size() - setA.size();
}


int main()
{
   string A, B;
   cout << "Enter string A: ";   getline( cin, A );
   cout << "Enter string B: ";   getline( cin, B );
   cout << "Number of common characters = " << numberInCommon( A, B );
}


Enter string A: Hello, world!
Enter string B: Cplusplus.com
Number of common characters = 2
Last edited on
The following version WILL allow duplicates ('l', 'l', 'o' in the example below).
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 <iostream>
#include <map>
#include <string>
#include <cctype>
#include <algorithm>
using namespace std;


void lower( string &s ) { for ( char &c : s ) c = tolower( c ); }


int numberInCommon( string A, string B )
{
   lower( A );
   lower( B );

   map<char,int> mapA, mapB;
   for ( char c : A ) mapA[c]++;
   for ( char c : B ) mapB[c]++;

   int counter = 0;
   for ( auto e : mapA ) counter += min( e.second, mapB[e.first] );

   return counter;
}


int main()
{
   string A, B;
   cout << "Enter string A: ";   getline( cin, A );
   cout << "Enter string B: ";   getline( cin, B );
   cout << "Number of common characters = " << numberInCommon( A, B );
}


Enter string A: Hello, world
Enter string B: Cplusplus.com
Number of common characters = 3
Topic archived. No new replies allowed.