I am coding for the problem in which we got to count the number of common characters in two strings. Main part of the count goes like this
for(i=0; i < st
You can do it with 2n:
int i,j, len1 = strlen(s1), len2 = strlen(s2);
unsigned char allChars[256] = { 0 };
int count = 0;
for( i=0; i<len1; i++ )
{
allChars[ (unsigned char) s1[i] ] = 1;
}
for( i=0; i<len2; i++ )
{
if( allChars[ (unsigned char) s1[i] ] == 1 )
{
allChars[ (unsigned char) s2[i] ] = 2;
}
}
for( i=0; i<256; i++ )
{
if( allChars[i] == 2 )
{
cout << allChars[i] << endl;
count++;
}
}
This is very simple. Take two int
arrays freq1
and freq2
. Initialize all its elements to 0
. Then read your strings and store the frequencies of the characters to these arrays. After that compare the arrays freq1
and freq2
to find the common characters.
First, your code does not run in O(n^2), it runs in O(nm), where n and m are the length of each string.
You can do it in O(n+m), but not better, since you have to go through each string, at least once, to see if a character is in both.
An example in C++, assuming:
std::vector<char> strIntersect(std::string const&s1, std::string const&s2){
std::vector<bool> presents(256, false); //Assuming ASCII
std::vector<char> intersection;
for (auto c : s1) {
presents[c] = true;
}
for (auto c : s2) {
if (presents[c]){
intersection.push_back(c);
presents[c] = false;
}
}
return intersection;
}
int main() {
std::vector<char> result;
std::string s1 = "El perro de San Roque no tiene rabo, porque Ramon Rodriguez se lo ha cortado";
std::string s2 = "Saint Roque's dog has no tail, because Ramon Rodriguez chopped it off";
//Expected: "S a i n t R o q u e s d g h l , b c m r z p"
result = strIntersect(s1, s2);
for (auto c : result) {
std::cout << c << " ";
}
std::cout << std::endl;
return 0;
}
No need to initialize and keep an array of 26 elements (numbers for each letter in alphabet). Just fo the following:
These steps are written considering Java programming language.
can be easily done using the concept of "catching" which is a sub-algorithm of hashing.
Their is a more better version in c++ : C++ bitset and its application A bitset is an array of bool but each Boolean value is not stored separately instead bitset optimizes the space such that each bool takes 1 bit space only, so space taken by bitset bs is less than that of bool bs[N] and vector bs(N). However, a limitation of bitset is, N must be known at compile time, i.e., a constant (this limitation is not there with vector and dynamic array)
As bitset stores the same information in compressed manner the operation on bitset are faster than that of array and vector. We can access each bit of bitset individually with help of array indexing operator [] that is bs[3] shows bit at index 3 of bitset bs just like a simple array. Remember bitset starts its indexing backward that is for 10110, 0 are at 0th and 3rd indices whereas 1 are at 1st 2nd and 4th indices. We can construct a bitset using integer number as well as binary string via constructors which is shown in below code. The size of bitset is fixed at compile time that is, it can’t be changed at runtime. For more information about bitset visit the site : https://www.geeksforgeeks.org/c-bitset-and-its-application
The code is as follows :
// considering the strings to be of lower case.
int main()
{
string s1,s2;
cin>>s1>>s2;
//Declaration for bitset type variables
bitset<26> b_s1,b_s2;
// setting the bits in b_s1 for the encountered characters of string s1
for(auto& i : s1)
{
if(!b_s1[i-'a'])
b_s1[i-'a'] = 1;
}
// setting the bits in b_s2 for the encountered characters of string s2
for(auto& i : s2)
{
if(!b_s2[i-'a'])
b_s2[i-'a'] = 1;
}
// counting the number of set bits by the "Logical AND" operation
// between b_s1 and b_s2
cout<<(b_s1&b_s2).count();
}