7

だから私はのセットを持っていますpairs<string ,string>

そしてfind()、ペアの「最初」にある単一の文字列を検索するために使用したいのですが、最初にその文字列を見つけた場合は、その関数から2番目に戻りたいと思います。

私の現在の試みは..

myList::iterator i;

i = theList.find(make_pair(realName, "*"));

return i->second;
4

3 に答える 3

6

C++11 は受け入れられますか?

auto it = find_if(theList.begin(), theList.end(),
    [&](const pair<string, string>& val) -> bool {
        return val.first == realName;
    });

return it->second;

または C++03 では、最初にファンクターを定義します。

struct MatchFirst
{
        MatchFirst(const string& realName) : realName(realName) {}

        bool operator()(const pair<string, string>& val) {
                return val.first == realName;
        }

        const string& realName;
};

次に、次のように呼び出します。

myList::iterator it = find_if(a.begin(), a.end(), MatchFirst(realName));
return it->second;

これは最初の一致のみを返しますが、あなたの質問から、あなたが期待しているのはそれだけのようです.

于 2013-05-31T11:27:14.413 に答える
2

これには使用できますstd::set<std::pair<std::string, std::string> >が、ペアの関係演算子は両方の要素を使用するため、カスタム比較オブジェクトが必要になります。そうは言っても、実際にはstd::map<std::string, std::string>代わりに a を使用する必要があるようです。

于 2012-03-23T17:02:30.307 に答える
1

<forの定義はstd::pair辞書順を実装し、""文字列の最小要素です。これを組み合わせると、次のようになります。

 typedef std::pair<std::string, std::string> StringPair;
 typedef std::set<StringPair> Set;

 std::string const* find_first(Set const& s, std::string const& key) {
   Set::const_iterator const it = s.lower_bound(std::make_pair(key, ""));

   // Check that it actually points to a valid element whose key is of interest.
   if (it == s.end() or it->first != key) { return 0; }

   // Yata!
   return &it->second;
 }

コツはlower_bound使い分けです。

より小さいと比較されない最初の要素を指す反復子を返しますvalue

  • が返された場合end()、興味深いものは何も見つかりませんでした。
  • それ以外の場合it->first >= keyは、ケースを取り除きます>(私たちには関係ありません)。

ただし、これは範囲の最初の要素のみを返すことを指摘します。すべての要素に興味がある場合は、次を試してください。

typedef std::pair<Set::const_iterator, Set::const_iterator> SetItPair;

SetItPair equal_range_first(Set const& s, std::string const& key) {
  StringPair const p = std::make_pair(key, "");
  return std::make_pair(s.lower_bound(p), s.upper_bound(p));
}

sこれは、最初の要素が に等しいノードの全範囲を返しkeyます。次に、この範囲を反復処理する必要があります。

for (Set::const_iterator it = range.first; it != range.second; ++it) {
  // do something
}

lower_boundまた、 orupper_boundが終了したかどうかを心配する必要もありません。

  • lower_bound返さend()れた場合はそうupper_boundであり、ループはスキップされます
  • iflower_boundが のノードを指している場合it->first > keyupper_boundは同じノードを指し、ループはスキップされます。

これが範囲の力です。特別なチェックを行う必要はありません。一致するものがない場合、範囲は空になるだけなので、それらのループは 1 回のチェックでスキップされます。

于 2012-03-23T20:18:58.880 に答える