检查vector是否具有所有可能的字符组合

时间:2018-10-26 04:44:06

标签: c++

我发现了许多其他问题,这些问题询问如何将'A''B''C'的所有可能组合创建为向量,但是 我正在尝试找到一种更简单的方法,该如何检查我的矢量是否包含“ A”,“ B”,“ C”(重复编号为AAA和CAA)的许多不同且相同的组合,是否包含这三个组合的所有可能组合字符。

我要使每个不同的字符组合等于一个不同的数字,并具有如下所示的switch语句,当匹配时将每个大小写更改为true,最后使用if语句检查所有情况是否为true。

但是我觉得似乎有更简单的方法可以做到这一点...

我还是c ++的新手,因此非常感谢任何帮助或建议

vector<string> myVector = {"ABC", "CBA"};
bool case1 = false;
for(int i = 0; i < myVector.size(); i++){
    switch(myVector[i]){
        case 11:
            case1 = true;
            break;
        ...
    }        
}

3 个答案:

答案 0 :(得分:0)

  • 将字符串的所有排列存储在vector
  • 将其与输入向量进行比较

一个最小的示例如下:

#include <algorithm>
#include <string>
#include <iostream>

int main()
{
    std::string s = "ABC";

    std::vector<string> perString;
    std::vector<string> inputVector = {"ABC", "ACB", "BAC", "BCA", "CAB", "CBA"}; 
    do {
        perString.push_back(s);
    } while(std::next_permutation(s.begin(), s.end()));
    if(perString == inputVector)
        std::cout<< "YES, the vector has all possible combinations of characters" << '\n';
    else
        std::cout<< "NO, It doesn't" << '\n';       

    return 0;
}

答案 1 :(得分:0)

  • 将向量过滤为仅包含有效字符串(因此,如果只希望来自- name: Wait for Elastic Cluster to be ready uri: url: https://abcdefbla.{{ lookup('env','ENV') }}.some.url.com/api/v1/clusters/elasticsearch/{{elasticClusterDetails.elasticsearchId}} method: GET user: admin password: "{{rootpw.stdout}}" force_basic_auth: yes return_content: yes validate_certs: no register: result until: resultA.json.healthy == false and "started" == "{{ resultA.json.status|lower }}" retries: 60 delay: 10 /* Button to play live news streaming */ @IBAction func liveNews(_ sender: Any) { guard let NewsUrl = URL(string: "http://cdn39.live247stream.com/A1TVuk/tv/playlist.m3u8") else { return } /* Create an AV PLAYER and passed the HLS URL to it */ let player = AVPlayer(url: NewsUrl) player.allowsExternalPlayback = true /* Setup a player view controller to handle the stream */ let playerViewController = AVPlayerViewController() playerViewController.player = player /* Using method of play() to load and play the stream */ present(playerViewController, animated: true){ playerViewController.player?.play() } "AZA"的字母,请拒绝'A'
  • 'B' / 'C'其内容。 (因此std::sort-> std::unique)。
  • 然后检查矢量大小是否符合预期大小("AAA", "ABA", "AAA"}{"AAA", "ABA"},取决于您的情况(3 ** 3)。

答案 2 :(得分:0)

解决此问题的一种方法是对要检查的组合向量进行排序(如果尚未进行排序),然后将元素与所有可能的(排序的)组合进行比较。由于排序阶段,这种方法的时间复杂度为O(C * log C),其中C是输入向量的元素数。

在可能的元素数量为 n 且选择的元素数量为 k 的情况下,

C可能会很大,所有重复的可能组合为 n k (在OP的示例中为3 ^ 3 = 27)。

另一种方法不需要对初始向量进行排序,也不需要实际生成排序后的组合,类似于在哈希表中搜索值。

如果可以对所有组合进行排序,那么也可以为它们建立索引。因此,您可以计算要测试的字符串代表的特定组合的“索引”,并计算找到的有效组合的数量。

这是可能的实现方式:

#include <iostream>
#include <string>
#include <vector>

// Transforms a string representing a combination into the index of that
// combination in the set of all possible combinations
size_t index_of(std::string const &candidate, std::string const &source);

// Check if the the vector 'combs' contains all the possible combinations
// of 'k' elements of string 'base'
bool are_there_all_the_possible_combinations(std::string const &base,
                                             size_t k,
                                             std::vector<std::string> const &combs);

int main()
{
    std::string base {"ABC"};

    std::vector<std::string> combs {
        "AAA", "AAB", "AAC", "ABA", "ABB", "ABC", "ACA", "ACB", "ACC",
        "BAA", "BAB", "BAC", "BBA", "BBB", "BBC", "BCA", "BCB", "BCC",
        "CAA", "CAB", "CAC", "CBA", "CBB", "CBC", "CCA", "CCB", "CCC"
    };

    size_t k = 3;

    std::cout << ( are_there_all_the_possible_combinations(base, k, combs)
                 ? "Yes\n" : "No\n" );              // <-- it should output 'Yes'

    combs.erase( std::remove( combs.begin(), combs.end(), "BCA" ), combs.end() );

    std::cout << ( are_there_all_the_possible_combinations(base, k, combs)
                 ? "Yes\n" : "No\n" );              // <-- it should output 'No'

    combs.push_back("BCA");              // <-- Note that now the vector isn't sorted.

    std::cout << ( are_there_all_the_possible_combinations(base, k, combs)
                 ? "Yes\n" : "No\n" );              // <-- it should output 'Yes'
}

// Calculate base ^ exponent (using size_t, not floating point math)
constexpr size_t ull_pow(size_t base, size_t exponent)
{
    size_t result = 1;
    for (;;)
    {
        if (exponent & 1)
            result *= base;
        exponent >>= 1;
        if (exponent == 0)
            break;
        base *= base;
    }
    return result;
}


// Counts the number of valid combinations and check if it equals the total
bool are_there_all_the_possible_combinations(std::string const &base,
                                             size_t k,
                                             std::vector<std::string> const &combs)
{
    size_t total_combinations = ull_pow(base.size(), k);
    std::vector<bool> combinations(total_combinations);

    size_t count = 0;
    for (auto const & str : combs)
    {
        if (str.size() != k)
        {
            // You can either ignore those mismatches or break
            continue;
        }
        size_t pos = index_of(str, base);
        if (pos == std::string::npos)
        {   
            // This string doesn't belong to the possible combinations. It's
            // unclear if OP want to ignore this case or consider it a mismatch
            continue;
        }
        if ( combinations[pos] )
        {
            // This is a duplicate. Again, it can be ignored or not.
            continue;
        }
        combinations[pos] = true;
        ++count;
    }

    return count == total_combinations;    
}

// Evaluate the index as a number in base n (number of elements in the base string)
size_t index_of(std::string const &candidate, std::string const &source)
{
    size_t result = 0, base = 1;
    for (auto c = candidate.crbegin(); c != candidate.crend(); ++c)
    {
        size_t pos = source.find(*c);
        if (pos == std::string::npos)
            return std::string::npos;
        result += pos * base;
        base *= source.size();
    }
    return result;
}