[英]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 ++這樣做的有效方法是什么?
謝謝
// 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 )。
st1
拆分為子字符串,並將它們全部放入std::set
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::vector
和std::sort
。 如果您只希望每個輸入在輸出中僅出現一次,而不管它在兩個輸入中出現的頻率如何,那么您可以在std::unique
,最后執行set_intersection
。
如果要支持迭代更新,則可能要使用std::set
或std::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.