If I have two strings, string str
and string prt
. I want to check if str
contains the characters of prt
irrespective of their indexes. Meaning, no matter how characters are arranged in prt
, if str
contains all of the characters of ptr
, then str
contains ptr
.
For example:
str="Pegasus"
prt="eas"
This should output true
because str
contains each character that prt
has.
Is there any pre-defined function to achieve this task?
CodePudding user response:
Is there any pre-defined function to achieve this task?
No. Since that's the only actual question in your question, I'm tempted to stop there.
We can write many different functions to do this - which ones are a good choice depend on things like how long your strings are, how much time you can justify spending on this, how important its performance is to your program, etc. etc.
The closest to a pre-defined function we can get is a (long) oneliner, like
bool contained = std::ranges::includes(std::set<char>{str.begin(), str.end()},
std::set<char>{prt.begin(), prt.end()});
It requires C 20 ranges, and creates a couple of temporary sets, each containing every unique letter in one of the strings.
If you don't have C 20 support or don't need it to fit on one line, you can easily materialize those temporary sets as in Remy's answer, and call the older std::includes
(although that's still preferable to using set_intersection
here).
There's an un-answered question in comments about repeated characters: this doesn't check whether str
contains at least as many of each distinct character as prt
does.
CodePudding user response:
You can use the function std::string::find
to determine whether a string contains a specific character.
Therefore, in order to determine whether str
contains all characters in ptr
, you can call std::string::find
once for every character in ptr
:
#include <iostream>
#include <string>
bool contains_all_characters( const std::string &str, const std::string &prt )
{
for ( char c : prt )
{
if ( str.find( c ) == std::string::npos )
{
return false;
}
}
return true;
}
int main()
{
std::string str, prt;
std::cout << "Enter string: ";
std::getline( std::cin, str );
std::cout << "Enter part: ";
std::getline( std::cin, prt );
if ( contains_all_characters( str, prt ) )
std::cout << "Does contain all characters.\n";
else
std::cout << "Does NOT contain all characters.\n";
}
This program has the following output:
Enter string: Pegasus
Enter part: eas
Does contain all characters.
Enter string: Pegasus
Enter part: eat
Does NOT contain all characters.
CodePudding user response:
You can std::sort()
the strings, and then use std::set_intersection()
to check if the result (the characters present in both strings) exactly equals the 2nd string, eg:
#include <string>
#include <algorithm>
#include <iterator>
bool containsPrt(std::string str, std::string prt)
{
std::sort(str.begin(), str.end());
std::sort(prt.begin(), prt.end());
std::string result;
std::set_intersection(
str.begin(), str.end(), prt.begin(), prt.end(),
std::back_inserter(result));
return result == prt;
}
Alternatively, you can use std::set
to collect the characters ignoring any duplicates, and then check the intersection of the set
s, eg:
#include <string>
#include <set>
#include <algorithm>
#include <iterator>
bool containsPrt(const std::string &str, const std::string &prt)
{
std::set<char> s1(str.begin(), str.end());
std::set<char> s2(prt.begin(), prt.end());
std::set<char> result;
std::set_intersection(
s1.begin(), s1.end(), s2.begin(), s2.end(),
std::inserter(result, result.begin()));
return result == s2;
}