簡體   English   中英

C ++:如何構建兩個以空格分隔的字符串的交集字符串?

[英]C++: how to build an intersection string of two space separated strings?

我有兩個用空格分隔的字符串...(X表示相同的符號)

st1 = "abc def kok...."
st2 = "kok bbr def ffe ...."

我想構造一個交集字符串,如下所示: common = "kok def"

用c ++這樣做的有效方法是什么?

謝謝

使用std::set_intersection

示例程序:

我假設您已經標記了字符串此解決方案似乎易於實現)。

// Data
std::vector<string> a,b;
a.push_back("abc");b.push_back("kok");
a.push_back("def");b.push_back("bbr");
a.push_back("kok");b.push_back("def");
a.push_back("foo");b.push_back("ffe");

// Allocate space for intersection
std::vector<string> v(a.size()+b.size());

// Sort as required by set_intersection
std::sort(a.begin(),a.end());
std::sort(b.begin(),b.end());
// Compute
std::vector<string>::iterator it = std::set_intersection(a.begin(),a.end(),b.begin(),b.end(),v.begin());

// Display
v.erase(it,v.end());
for(std::vector<string>::iterator it = v.begin();it < v.end(); ++it) std::cout<<*it<<std::endl;

令牌(或子字符串)數量的復雜度應為O(n log n )。

  1. st1拆分為子字符串,並將它們全部放入std::set
  2. st2拆分為子字符串,並檢查每個字符串是否存在於步驟1中創建的集合中。

這將給定O(n log n)執行時間。 您必須在兩個字符串之間循環一次。 對於每個元素,從集合中插入和檢索通常為O(log n) ,從而得出O(n log n)

如果您可以將基於哈希的集合(或其他一些無序集合)與O(1)插入和檢索復雜度一起使用,則可以將復雜度降低為O(n)

為了進一步擴展您已經獲得的答案,基本上有兩個因素需要考慮,您尚未指定。 首先,如果輸入中包含重復的元素,則是否要考慮將這些元素用於輸出。 例如,給定的輸入如下:

st1 = "kok abc def kok...."
st2 = "kok bbr kok def ffe ...."

由於“ kok”在兩個輸入中都出現兩次,因此“ kok”應在輸出中出現一次還是兩次?

第二個是您的使用模式。 您是否具有讀取所有輸入,然后生成單個輸出的模式,或者是更具迭代性的模式,您可能在其中讀取一些輸入,生成一個輸出,讀取添加到前一個輸入的更多輸入,生成另一個輸出,等等上?

如果您要讀取所有輸入,然后生成一個輸出,則可能要使用std::vectorstd::sort 如果您只希望每個輸入在輸出中僅出現一次,而不管它在兩個輸入中出現的頻率如何,那么您可以在std::unique ,最后執行set_intersection

如果要支持迭代更新,則可能要使用std::setstd::multiset (每個輸出的std::set都是唯一的,如果重復輸入應該給出重復的結果,則為std::multiset )。

編輯:基於輸入中沒有重復項,一個非常快速的簡單實現將是這樣的:

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

int main() {   
    std::string st1("abc def kok");
    std::string st2("kok bbr def ffe");

    std::istringstream s1(st1);
    std::istringstream s2(st2);

    // Initialize stringstreams. Whine about most vexing parse.
    std::set<std::string> words1((std::istream_iterator<std::string>(s1)), 
                                 std::istream_iterator<std::string>());

    std::set<std::string> words2((std::istream_iterator<std::string>(s2)), 
                                 std::istream_iterator<std::string>());

    std::ostringstream common;

    // put the intersection into common:
    std::set_intersection(words1.begin(), words1.end(), 
                          words2.begin(), words2.end(),
                          std::ostream_iterator<std::string>(common, " "));

    std::cout << common.str();  // show the result.
    return 0;
}

暫無
暫無

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

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