简体   繁体   中英

Inside a std::string, is it possible to find the first of a set of strings without using a loop?

Inside a std::string, is it possible to find the first of a set of strings without using a loop?

Eg:

std::string str("aaa bbb ccc ddd eee fff ggg");
std::vector<std::string> vs;
vs.push_back("ccc");
vs.push_back("fff");
size_t pos = 0
pos = str.find(vs, pos);      //< pseudo code

Thank you!

最简单的解决方案是使用像Boost.Regex这样的正则表达式库,如下所示:

"\\b(ccc|fff)\\b"

You could split the string (using a stringstream) into a vector and then use std::find_first_of with the four iterators.

Here is a complete code example

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

using namespace std;

int main(void)
{
  string str("aaa bbb ccc ddd eee fff ggg");
  vector<string> vs;
  vs.push_back("ccc");
  vs.push_back("fff");
  vector<string> scheck;

  istringstream instr(str);
  copy(istream_iterator<string>(instr),
       istream_iterator<string>(),
       back_inserter(scheck));

  vector<string>::iterator it = find_first_of (scheck.begin(), scheck.end(), vs.begin(), vs.end());
  if (it != scheck.end())
    cout << "first match is: " << *it << endl;

  return 0;
}

It's not really possible unless you use Regular Expression. Boost.Regex could be your friend.

Im not sure but I think that :

str.find() will return an iterator("index") to the first instance found.

but I think you should have :

size_t pos1 = str.find(vs.begin() , 0);
size_t pos2 = str.find(vs.end() , 0); 
// since you have only ccc and fff , ccc is on begin(), and fff on end()

??? but im not sure.

edit : and I dont think you can find occurances of all strings in the vector without a loop, unless you do loop unwinding.

When you say without a loop do you mean without a handwritten loop because algorithms use loops in their implementation.

As you can do find for an individual string you can do something with vec.begin(), vec.end() str.find and probably a bit of boost::bind.

Not sure what you want to do with all these finds though. Something like this:

std::vector< std::string::size_type > locations;
locations.reserve( vec.size() );
std::transform( vec.begin(), vec.end(), std::back_inserter(locations), boost::bind( &std::string::find, str, _1 ) );

would generate for you a vector of the position where those items were found. You can write your own functor if you want something more advanced, eg keeping state, although if the code really gets that complicated I don't see the value of avoiding the loop.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM