Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checking if a character occurs at least N times in the string. Any solution in algorithms?

This question is not hard in terms of getting solution, but I would like to know if any C++ function or algorithm is available to solve it.

I got this thought while going through this question Count character occurrences in a string in C++

So would like to know if we have any option other than writing a function from scratch to check if there is a specific number of occurrences of a character in the string. For example let us say:

std::string s = "a_b_c_d_e_f_g_h_i_j_k_l_m";

and we want to find if there are at least 2 '_' in the string. If we use std::count it will return the count of all '_'. std::count_if will also behave in similar way. I can write a code to loop through the string and break as soon as the count reaches 2, but I would like to know if we have some existing solution in C++ algorithms or functions.

Thought process here is, if we get a very long string as an input and criteria of doing something is based on whether there is at least n number of occurrences of a specific character, then it is a waste to traverse through the whole string.

like image 368
novice Avatar asked Dec 13 '22 08:12

novice


2 Answers

std::find_if with a proper functor would do the job:

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();

Though, I would prefer to create a new function for that, let's call it 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;
                          });
}

With a simpler usage:

bool found = find_if_n(s1.begin(), s1.end(), [] (char c) {
                  return c == '_';
             }, 2) != s1.end();
like image 114
Amir Kirsh Avatar answered Feb 02 '23 00:02

Amir Kirsh


You can use for example std::find_if. Here you are

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

The program output is

3

That is the algorithm stops its execution as soon as it found the second character '_'.

like image 32
Vlad from Moscow Avatar answered Feb 02 '23 00:02

Vlad from Moscow