搜索字符串是否至少包含一次从 0 到 9 的所有数字的最有效方法

Most Efficient way to search if a string contain all numbers from 0 to 9 at least once?

本文关键字:数字 方法 有效 是否 字符串 包含一 搜索      更新时间:2023-10-16
bool IsWin(string A, string B)
{
    vector<int> vec = {0,1,2,3,4,5,6,7,8,9};
    for(long int i=0;i<A.length();i++){
        vec[A[i]-'0'] = 11;
    }
    if(IsArray(vec)){    //IsArray(vec) It just checks whether all elements are 11.
        return true;
    }
    for(long int i=0;i<B.length();i++){
        vec[B[i]-'0'] = 11;
    }
    return IsArray(Array);
}

似乎显而易见的方式是这样的:

bool has_all_digits(std::string const &input) { 
    std::vector<char> present(10, 0);
    for (auto c : input)
        present[c - '0' ] = 1;
    return std::find(present.begin(), present.end(), 0) == present.end();
}

在这种情况下,std::bitset可能是解决此问题的最有效方法。

bool check(string s){
    std::bitset<10> digits;
    int digitCounter = 0;
    int index;
    for (char c : s){
        if (std::isdigit(c)){
            index = c - '0';
            if (!digits[index]){
                digitCounter++;
                digits[index] = true;
                if (digitCounter == 10)
                    return true;
            }       
        }
    }
    return false;
}

如果 A 或 B 包含数字旁边的任何内容,这将有超出 vec 的范围例外。在循环之间,vec 需要重新初始化。此外,最后一行应IsArray(vec)。为什么不使用vector<bool> vec

在你关心效率之前,算法应该工作并且是异常安全的。

没有基准测试,任何关于性能的讨论都是毫无意义的。所以你需要测量,然后测量更多。

考虑到这一点,这里有一个针对具有密集数字的长字符串优化的版本,即很有可能将所有数字包含在一个小子字符串中。该函数将在找到所有数字后立即退出,并且不会继续执行字符串的其余部分:

auto has_all_digits(const std::string& str) -> bool
{
    std::array<int, 10> digits = {};
    int num_digits = 0;
    for (char ch : str)
    {
        if (!is_digit(ch))
            continue;
        // here is a cool branchless trick
        // to count unique digits
        int x = 1;
        std::swap(digits[ch - '0'], x); // put 1 to digits and get the old value in x
        num_digits += 1 - x; // increment if the old value was 0
        if (num_digits == 10)
            return true;
    }
    return false;    
}

同样,不要忘记测量并查看此算法是否确实适合您的用例。

相关文章: