检查字符是否在字符串中至少出现了N次算法有什么解决方案吗?

问题描述

就获得解决方案而言,这个问题并不难,但是我想知道是否有任何C ++函数或算法可以解决该问题。

遇到这个问题Count character occurrences in a string in C++

时,我想到了

因此,我们想知道除了从头开始编写函数检查字符串中是否存在特定数量的字符外,是否还有其他选择。 例如,让我们说:

INFO 2020-08-13 13:36:33.494 uvicorn.protocols.http.h11_impl:send - 127.0.0.1:52660 - "GET 
/url1/url2/ HTTP/1.1" 400 params={"some": value,"some1":value}

我们要查找字符串中是否至少有2个“ _” 。 如果我们使用<input v-model="field.user_value" :name="field.name" v-on:input="validateTextInput(field.field_validations,$event)" type="text" class="form-control input-md form-control"/> methods: { validateTextInput(validations,event) { if(validations.req=='required') { if(event.target.value=='') { alert('This field is required'); return false; } if(validations.allowed=='string') { } } ,它将返回所有'_'的计数。 with cte as ( select (select count(x) from table1 a,table2 b where ~~;) as column1,(select count(x) from table3 a,table4 b where ~~;) as column2,(select count(x) from table5 a,table6 b where ~~;) as column3 from dual ) select c.*,column1 + column2 + column3 as total from cte c; 的行为也将类似。 我可以编写一个代码来遍历字符串并在计数达到2时立即中断,但是我想知道我们是否在C ++算法或函数中已有一些解决方案。

这里的思想过程是,如果我们得到一个很长的字符串作为输入,并且执行某项操作的标准是基于是否至少出现n次特定字符,那么遍历整个字符串是一种浪费字符串。

解决方法

std::find_if和合适的函子可以完成这项工作:

std::string s1 = "a_b_c_d_e_f_g_h_i_j_k_l_m";
int count = 0;
bool found =
    std::find_if(s1.begin(),s1.end(),[&count] (char c) {
           return c == '_' && ++count == 2;
        }) != s1.end();

尽管如此,我更愿意为此创建一个新函数,我们将其称为find_if_n

template<typename Iterator,typename Predicate>
Iterator find_if_n(Iterator begin,Iterator end,Predicate&& pred,int n) {
    return std::find_if(begin,end,[&pred,&n] (const auto& v) {
                             return pred(v) && --n == 0;
                          });
}

使用更简单:

bool found = find_if_n(s1.begin(),[] (char c) {
                  return c == '_';
             },2) != s1.end();
,

您可以使用例如std::find_if。你在这里

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

int main() 
{
    std::string s = "a_b_c_d_e_f_g_h_i_j_k_l_m";
    
    std::string::size_type n = 0;
    
    auto it = std::find_if( std::begin( s ),std::end( s ),[&n]( const auto &c )
                             {
                                 return c == '_' && ++n == 2;
                             } );
                   
    std::cout << std::distance( std::begin( s ),it ) << '\n';                 
                       
    return 0;
}

程序输出为

3

这是算法在找到第二个字符“ _”后立即停止执行。

,

一种可能的解决方案是使用std::all_of(),因为该函数在谓词为false时停止:

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

int main()
{
    std::string str = "a_b_c_d_e_f_g_h_i_j_k_l_m";
    char search = '_';
    int count = 0,limit = 2;
    
    std::all_of(str.begin(),str.end(),[&search,&count,&limit](const char& c){
        std::cout << c << " ";
        if (c == search){
            count++;
        }
        return count < limit;
    });
    
    std::cout << "\nContains at least " 
    << limit << " " << "'" << search << "' ? " << count 
    << std::endl;
}

因此,只要您的谓词错误,您就可以浏览字符串。
在这种情况下,您仅检查了4个字符来代替完整的字符串: a _ b _

,

使用c ++ 20,您可以编写以下函数:

namespace sr = std::ranges;
namespace sv = std::ranges::views;

bool has_count_elements(auto&& range,int count,auto elem)
{
    auto match = [=] (auto c) { return c == elem; };

    auto matches = sv::filter(range,match) | sv::drop(count - 1);

    return not sr::empty(matches);
}

并像这样使用它:

int main() 
{
    std::string s = "a_b_c_d_e_f_g_h_i_j_k_l_m";
    std::cout << has_count_elements(s,2,'_');   // prints 1
} 

由于filterview懒惰地评估了范围,即仅根据需要进行计算,因此仅找到count个元素并且begin和{ {1}}在评估end时有所不同。

此外,您还应约束函数,以使sr::emptyelem的基础类型具有相同的类型。

这里是demo


我确定我已经看过这个问题了,这个答案在SO的某处,但是我似乎找不到。