簡體   English   中英

查找兩個字符串向量的交點

[英]Finding the intersection of two vectors of strings

我有兩個字符串向量,並想找到兩個字符串中都存在的字符串,並用公共元素填充第三個向量。 編輯:我添加了帶有相應輸出的完整代碼清單,以使事情變得清晰。

  std::cout << "size " << m_HLTMap->size() << std::endl;

  /// Vector to store the wanted, present and found triggers
  std::vector<std::string> wantedTriggers;
  wantedTriggers.push_back("L2_xe25");
  wantedTriggers.push_back("L2_vtxbeamspot_FSTracks_L2Star_A");
  std::vector<std::string> allTriggers;

  // Push all the trigger names to a vector
  std::map<std::string, int>::iterator itr = m_HLTMap->begin();
  std::map<std::string, int>::iterator itrLast = m_HLTMap->end();
  for(;itr!=itrLast;++itr)
  {
    allTriggers.push_back((*itr).first);
  }; // End itr

  /// Sort the list of trigger names and find the intersection
  /// Build a typdef to make things clearer
  std::vector<std::string>::iterator wFirst = wantedTriggers.begin();
  std::vector<std::string>::iterator wLast = wantedTriggers.end();
  std::vector<std::string>::iterator aFirst = allTriggers.begin();
  std::vector<std::string>::iterator aLast = allTriggers.end();

  std::vector<std::string> foundTriggers;

  for(;aFirst!=aLast;++aFirst)
  {
    std::cout << "Found:" << (*aFirst) << std::endl; 
  };

  std::vector<std::string>::iterator it;

  std::sort(wFirst, wLast);
  std::sort(aFirst, aLast);
  std::set_intersection(wFirst, wLast, aFirst, aLast, back_inserter(foundTriggers));

  std::cout << "Found this many triggers: " << foundTriggers.size() << std::endl;
  for(it=foundTriggers.begin();it!=foundTriggers.end();++it)
  {
    std::cout << "Found in both" << (*it) << std::endl;
  }; // End for intersection

輸出是

這是部分輸出,向量中有1000多個元素,因此我沒有包括完整的輸出:

Found:L2_te1400
Found:L2_te1600
Found:L2_te600
Found:L2_trk16_Central_Tau_IDCalib
Found:L2_trk16_Fwd_Tau_IDCalib
Found:L2_trk29_Central_Tau_IDCalib
Found:L2_trk29_Fwd_Tau_IDCalib
Found:L2_trk9_Central_Tau_IDCalib
Found:L2_trk9_Fwd_Tau_IDCalib
Found:L2_vtxbeamspot_FSTracks_L2Star_A
Found:L2_vtxbeamspot_FSTracks_L2Star_B
Found:L2_vtxbeamspot_activeTE_L2Star_A_peb
Found:L2_vtxbeamspot_activeTE_L2Star_B_peb
Found:L2_vtxbeamspot_allTE_L2Star_A_peb
Found:L2_vtxbeamspot_allTE_L2Star_B_peb
Found:L2_xe25
Found:L2_xe35
Found:L2_xe40
Found:L2_xe45
Found:L2_xe45T
Found:L2_xe55
Found:L2_xe55T
Found:L2_xe55_LArNoiseBurst
Found:L2_xe65
Found:L2_xe65_tight
Found:L2_xe75
Found:L2_xe90
Found:L2_xe90_tight
Found:L2_xe_NoCut_allL1
Found:L2_xs15
Found:L2_xs30
Found:L2_xs45
Found:L2_xs50
Found:L2_xs60
Found:L2_xs65
Found:L2_zerobias_NoAlg
Found:L2_zerobias_Overlay_NoAlg
Found this many triggers: 0

可能的原因

我開始認為編譯代碼的方式應該受到指責。 我目前正在使用ROOT(物理數據分析框架)進行編譯,而不是進行獨立的編譯。 我感到它在STL算法庫中不能很好地工作,這就是問題的根源,特別是考慮到似乎有很多人為他們工作的代碼。 我將嘗試做一個獨立的編譯並重新運行。

傳遞foundTriggers.begin()並將foundTriggers空,因為輸出參數不會導致將輸出推送到foundTriggers 相反,它將在不調整向量大小的情況下將迭代器增加到向量的末尾,從而隨機破壞內存。

您要使用插入迭代器:

std::set_intersection(wFirst, wLast, aFirst, aLast, 
    std::back_inserter(foundTriggers));

更新:正如注釋中所指出的,向量的大小已調整為至少足夠大以容納結果,因此您的代碼應該可以工作。 請注意,您應該使用從set_intersection返回的迭代器來指示交點的結尾-您的代碼將忽略它,因此您還將迭代輸出末尾的空字符串。

您能否發布一個完整的測試用例,以便我們可以看到交集是否實際上為空?

畢竟,您的 allTrigers向量 空。 你永遠不會重置 itr到地圖的開始,當你加油吧。

編輯:

實際上,您永遠不會重置aFirst

for(;aFirst!=aLast;++aFirst)
  {
    std::cout << "Found:" << (*aFirst) << std::endl; 
  };

  // here aFirst == aLast

  std::vector<std::string>::iterator it;

  std::sort(wFirst, wLast);
  std::sort(aFirst, aLast);  // **** sorting empty range ****
  std::set_intersection(wFirst, wLast, aFirst, aLast, back_inserter(foundTrigger));
                               //      ^^^^^^^^^^^^^^
                               // ***** empty range *****

我希望您現在可以看到為什么縮小變量范圍的好習慣。

您永遠不會使用set_intersection的返回值。 在這種情況下,您可以使用它在set_intersection返回之后或為for循環的上限來調整foundIterators大小。 否則,您的代碼似乎可以正常工作。 我們能否看到完整的可編譯程序及其實際輸出?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM