2011-12-22 20 views
7

の値を持つvector<string> vectorStringsがあります。私は、入力文字列中のベクトル中の文字列のどれかが最初に出現するのを発見したい。ベクトルからの最初の文字列の検索<string>

ベクトル内の指定された文字列の

InputStr = "this certainly helps"; 

は、私が"cer"を言うための方法は、位置5で最初に出現したのでしょう。


int min = 9999999; 
string first; 

for(int i = 0; i < vectorStrings.size(); i++) 
{ 
    int pos = InputStr.find(vectorStrings[i]); 

    if(pos == string::npos) 
     continue; 

    if(pos < min) 
    { 
     min = pos; 
     first = vectorStrings[i]; 
    } 
} 

// values of min and first gives which string occurred first 
// and at the position of it in the input string 

この実装では動作しますが、私はブーストライブラリやSTDライブラリでこれを行うために、よりエレガントな方法が存在するかどうかを知りたいでしょう。私は、Windows上で作業して、私は、このタスクのための一般的なブーストアルゴリズムを知らないのVisual Studio 2010

+0

私はエレガントなことは知らないが、私は外側のループが終わって行くべきだと思いますあなたのベクトルの文字列の文字列と内側のループ(あなたの場合は - find)。もっと効率的だと思います。 –

+1

min :: string :: size_type min = string :: npos; '(これは' pos == npos'テストを取り除くこともできます)。 – UncleBens

+0

イテレータを使用できます。 ;) –

答えて

8

これはMapReduceの問題です。

最初に、位置であるvector<string>からvector<int>に移動し、その値を最小値で1つの値に減らしたい場合は、縮小します。まず、地図。これはstd::transformです。

std::vector<std::string> stuff; 
std::string input; 
// fill stuff and input 
std::vector<int> positions; 
std::transform(
    stuff.begin(), 
    stuff.end(), 
    std::back_inserter(positions), 
    [&](std::string& stuff) { 
     return input.find(stuff); 
    } 
); 

今、私たちは単に減らす、最小の要素を取得するためにstd::min_elementを使用しています。

auto iterator = std::min_element(positions.begin(), positions.end()); 
int index = *iterator; 

が発見された文字列を検索するには、それはイテレータ演算の単純なビットです:

string found = stuff[iterator - positions.begin()]; 
+0

私はそれを行うために、私はC++ 03非ブーストの同等物を書くことを試みました。私が 'find 'のためにメンバー関数ポインタをキャストした後、私は' mem_fun_ref'が単項関数のためだけに働くことを思い出しました。ちょうどOPが同じように試みる場合に備えて。 – pmr

1

を使用しています

。 あなたのアルゴリズムは正しく、小さなディメンションでうまくいくはずです。文字列のベクトルが大きい場合は、このタスクのために少し複雑なツリー構造を使いたいかもしれません。たとえば、文字列のベクトルをツリーに整理して検索を高速化することができます。 サフィックスツリーも使用できます。

1
class Find 
{ 
public: 
    std::vector<std::string> vectorStrings; 
    std::map<size_t, std::string> positions; 

    size_t find(std::string str) 
    { 
     for(std::vector<std::string>::iterator i = vectorStrings.begin(); 
      i != vectorStrings.end(); 
      ++i) 
     { 
      positions[str.find(*i)] = *i; 
     } 

     return (*(positions.begin())).first; 
    } 
}; 
関連する問題