2015-11-12 177 views
-2

我感到困惑的是,我有一個由字符串作爲關鍵的size_t的地圖和字符串作爲值。如何串推進迭代器C++通過每一個字符

std::multimap<size_t, std::string> wordMap; 

然後,我有一對存儲那時,我想通過equal_range到equal_range年底開始迭代與4大小的所有字符串的equal_range。開始是我的pair.first和end是我的pair.second。我如何遍歷我的pair.first指向的每個字符,然後將它與pair.first和pair.second之間的每個單詞進行比較?

pair<multimap<size_t, string>::iterator, multimap<size_t, string>::iterator> key_range; 
key_range = wordMap.equal_range(n); 

基本上我想比較word1中的每個字母與word2中的每個字符。 將word2前進itr2到下一個單詞,並將每個字母與word1中的每個字母進行比較。對每個單詞做這個事情,然後將itr1這是word1到另一個單詞,並將其與每個單詞進行比較。 我將如何獲得itr2指向的每個角色?我認爲第一個for循環爲第一個迭代器完成了這一點,但我不知道如何爲itr2做到這一點。

for (word_map::iterator itr = key_range.first; itr != key_range.second; itr++) { //this loop will iterate through every word to be compared 
for (word_map::iterator itr2 = next(key_range.first); itr2 != key_range.second; itr2++) { //this loop will iterate through every word being compared against itr1 
int i = 0; 
int hit = 0; 
for (char& c1 : itr->first) { 
      char& c2{ (itr2)->first[i] }; 
    if(c1 != c2) 
    hit++; 
i++; 
} 
} 

我想在每一個字每一個字母,只要它們具有相同的字符串大小進行相互比較。然後,如果命中== 1,這意味着單詞只有1個字符,並且它們應映射或存儲在某種類型的STL容器中,並將它們分組。我還是新來的STL,所以我在想一套,但我需要更多地閱讀它。

+0

爲(word_map:迭代itr2 = *(key_range ++)。首先是我試過 – user5544610

+0

你可以用'的std ::未來(key_range.first)'到一個後獲得的迭代器。它贏得了」如果提供的迭代器在最後,那麼t工作 –

+0

所以,你基本上想要比較第一個字(由key_range.first指向)和其他每個字(即對每個後續迭代器)? – notmyfriend

回答

1

首先,如果您提供了一個最小的可編譯示例,您將更有可能獲得幫助。我假設你的話是std::string這個答案,但你知道他們說什麼假設。

有喜歡它在Boost實施專爲同時遍歷多張收藏「ZIP」的算法,但我不認爲有什麼標準庫相媲美。

一個簡單但不愉快的方法只是手動迭代兩個字符串。這將輸出兩個單詞中的每個字母,直到一個單詞結束,或者存在差異。

注意所有的繁瑣位:您需要確保兩個迭代器的情況下,在任何時候都有效之前,另外一個字結束,並制定出實際發生的情況是有點麻煩。

#include <string> 
#include <iostream> 

int main() 
{ 
    std::string word1 = "capsicum"; 
    std::string word2 = "capsicube"; 

    std::string::iterator it1 = word1.begin(); 
    std::string::iterator it2 = word2.begin(); 

    while (it1 != word1.end() && it2 != word2.end()) 
    { 
      // characters are different! 
      if (*it1 != *it2) 
        break; 

      // characters are the same 
      std::cout << "Both have: " << *it1 << std::endl; 

      // advance both iterators 
      ++it1; 
      ++it2; 
    } 

    if (it1 == word1.end() && it2 == word2.end()) 
    { 
      std::cout << "Words were the same!" << std::endl; 
    } 
    else if (it1 == word1.end()) 
    { 
      std::cout << "Word 1 was shorter than word 2." << std::endl; 
    } 
    else if (it2 == word2.end()) 
    { 
      std::cout << "Word 1 was longer than word 2." << std::endl; 
    } 
    else 
    { 
      std::cout << "Words were different after position " << (it1 - word1.begin()) 
         << ": '" << *it1 << "' vs '" << *it2 << "'" << std::endl; 
    } 
} 
+0

感謝那種幫助。但我感到困惑的是,我有一個由字符串的size_t作爲鍵組成的映射,字符串作爲值。然後我有一對存儲所有大小爲4的字符串的equal_range。然後我想遍歷該equal_range的開始到equal_range的末尾。開始是我的pair.first和end是我的pair.second。 我將如何遍歷我的pair.first指向的每個字符,然後將它與pair.first和pair.second之間的每個單詞進行比較? – user5544610

+0

@ user5544610 - 您是否可以更新您的問題以包含此附加信息,最好以簡單但有效的代碼形式? – notmyfriend

+0

好吧,我更新了我原來的問題,並提供了我寫的所有代碼。 – user5544610

0

最新的答案,因爲問題已被顯着更新。我仍然不確定這是否會按照您的要求進行,但我認爲您應該可以使用它來獲得您想要的位置。

我寫這爲minimal, complete, verifiable example,這是理想的,你應該如何提出自己的問題。爲了簡潔/可讀性,我還使用了C++ 11功能。

希望內嵌批註,將充分解釋的東西給你,至少能夠做自己的研究,任何你不完全瞭解,但隨時如果您有任何更多的問題發表評論。其基本思路是存儲的第一個字(使用key_range.first迭代器),然後開始從下使用std::next()迭代器迭代,直到我們在key_pair.second到達終點迭代器。

然後這給我們word1以外的循環,和word2在循環內將被設置爲列表中的每個其他單詞。然後,我們使用我在其他答案中發佈的「雙重交互」技術來逐字比較每個單詞。

#include <map> 
#include <string> 
#include <iostream> 

int 
main() 
{ 
    std::multimap<size_t, std::string> wordMap; 

    wordMap.insert({4, "dogs"}); 
    wordMap.insert({4, "digs"}); 
    wordMap.insert({4, "does"}); 
    wordMap.insert({4, "dogs"}); 
    wordMap.insert({4, "dibs"}); 

    // original type declaration... 
    // std::pair<std::multimap<size_t, std::string>::iterator, std::multimap<size_t, std::string>::iterator> key_range; 

    // C++11 type inference... 
    auto key_range = wordMap.equal_range(4); 

    // make sure the range wasn't empty 
    if (key_range.first == key_range.second) 
    { 
      std::cerr << "No words in desired range." << std::endl; 
      return 1; 
    } 

    // get a reference to the first word 
    std::string const& word1 = key_range.first->second; 


    std::cout << "Comparing '" << word1 << "' to..." << std::endl; 

    // loop through every iterator from the key_range, skipping for the first 
    // (since that's the word we're comparing everything else to) 
    for (auto itr = std::next(key_range.first); itr != key_range.second; ++itr) 
    { 
      // create a reference for clarity 
      std::string const& word2 = itr->second; 

      std::cout << "... '" << word2 << "'"; 

      // hit counter; where hit is defined as characters not matching 
      int hit = 0; 

      // get iterators to the start of each word 
      auto witr1 = word1.begin(); 
      auto witr2 = word2.begin(); 

      // loop until we reach the end of either iterator. If we're completely 
      // confident the two words are the same length, we could only check 
      // one of them; but defensive coding is a good idea. 
      while (witr1 != word1.end() && witr2 != word2.end()) 
      { 
        // dereferencing the iterators will yield a char; so compare them 
        if (*witr1 != *witr2) 
          ++hit; 

        // advance both iterators 
        ++witr1; 
        ++witr2; 
      } 

      // do something depending on the number of hits 
      if (hit <= 1) 
      { 
        std::cout << " ... close enough!" << std::endl; 
      } 
      else 
      { 
        std::cout << " ... not a match, " << hit << " hits." << std::endl; 
      } 
    } 
} 
+0

漂亮的回答:D – user5544610

+0

auto witr1 = word1.begin();這是一個字符串迭代器嗎?只是爲了澄清。 – user5544610

+0

@ user5544610 - 是的,它應該等同於'std :: string :: const_iterator witr1 = word1.begin();' – notmyfriend