Home > Mobile >  How to check if a string contains all of the characters of another string?
How to check if a string contains all of the characters of another string?

Time:06-14

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;
}

Online Demo

Alternatively, you can use std::set to collect the characters ignoring any duplicates, and then check the intersection of the sets, 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;
}

Online Demo

  •  Tags:  
  • c
  • Related