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.
/* 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.
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.
#include <iostream>
#include <map>
#include <string>
#include <cctype>
#include <algorithm>
usingnamespace 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