C++ 搜索字符串是否至少包含一次从0到9的所有数字的最有效方法? bool-IsWin(字符串A、字符串B) { 向量vec={0,1,2,3,4,5,6,7,8,9}; 对于(long int i=0;i

C++ 搜索字符串是否至少包含一次从0到9的所有数字的最有效方法? bool-IsWin(字符串A、字符串B) { 向量vec={0,1,2,3,4,5,6,7,8,9}; 对于(long int i=0;i,c++,string,algorithm,C++,String,Algorithm,来说,最明显的方式是: 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

来说,最明显的方式是:

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有所有数字(std::string const&input){
std::存在病媒(10,0);
用于(自动c:输入)
存在[c-'0']=1;
返回std::find(present.begin(),present.end(),0)=present.end();
}

如果A或B包含数字以外的内容,则vec将有超出范围的异常。 循环之间需要重新初始化vec。 此外,最后一行应该是
IsArray(vec)
。 为什么不使用向量向量向量呢

在考虑效率之前,算法应该是有效的,并且是异常安全的。

在这种情况下,可能是解决这个问题最有效的方法

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();
}
bool检查(字符串s){
std::位集数字;
int数字计数器=0;
整数指数;
用于(字符c:s){
if(标准::isdigit(c)){
指数=c-‘0’;
如果(!位[索引]){
数字计数器++;
数字[索引]=真;
如果(数字计数器==10)
返回true;
}       
}
}
返回false;
}

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

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

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;
}
auto拥有所有数字(const std::string&str)->bool
{
std::数组数字={};
int num_位=0;
用于(字符ch:str)
{
如果(!是_位(ch))
持续
//这里有一个很酷的无分支技巧
//计算唯一数字的步骤
int x=1;
std::swap(数字[ch-'0'],x);//将1放入数字,然后在x中获取旧值
num_digits+=1-x;//如果旧值为0,则递增
如果(数字=10)
返回true;
}
返回false;
}

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

请花一些时间阅读,尤其是命名为和的部分。还有请和。最后,请学习如何创建。如果您有一个可行的解决方案,但您正在寻找更有效的方法,您可以尝试或@bhavayan并定义effic客户端。Percormance智能,内存智能,代码更少?@添加“可读”到那个列表。@bhavayanand然后使用分析器找到瓶颈。你能解释一下这段代码吗?我是编程新手。返回和查找函数在这段代码中做什么?@bhavayanand你可以告诉自己。这是一个有竞争力的编程问题。所以vector永远不会得到除了数字以外的任何输入,根据c问题中给出的约束。在std::swap函数中,您将x的值与一些未初始化的数字[]元素交换。x不会得到一些垃圾值吗?如果这是一些愚蠢或明显的问题,请原谅我是编程新手。@bhavayanand
数字
已初始化。请参阅
={}
但大括号中没有值。这是否意味着所有值都要初始化为0或NULL?@bhavayanand
0
在这种情况下。好吧,我现在知道了。从您的ans中,我了解了自动、基于范围的for循环、数组默认构造函数,这是我以前不知道的。最后一件事,在第一行,->bool这是什么意思?仍然效率不够。19次提交中有16次超时。请立即尝试。如果不够,我想看看submissions采样器。
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;    
}