如何在C ++中获得两个向量共有的字符?

时间:2010-03-08 19:29:17

标签: c++ comparison vector

我试图比较两个矢量对象,并返回一个包含两个矢量中出现的所有字符的矢量。

如果不编写一些非常复杂的手动方法,我将如何解决这个问题,该方法将第一个向量中的每个字符与第二个向量中的每个字符进行比较,并使用if将其添加到第三个向量(如果它们将被返回)匹配。

也许我缺乏对矢量的真实经验让我想象这会比实际更难,但我怀疑有一些我通过搜索无法找到的简单方法。

7 个答案:

答案 0 :(得分:10)

我认为你正在寻找std::set_intersection。必须对源向量进行排序。如果您不关心输出向量的顺序,则可以始终在源向量的已排序副本上运行它。

而BTW,手动天真的方式并不是非常复杂。给定两个源向量s1s2以及目标向量dest,您可以编写如下内容:

for (std::vector<char>::iterator i = s1.begin(); i != s1.end(); ++i)
{
    if (std::find(s2.begin(), s2.end(), *i) != s2.end())
    {
        dest.push_back(*i);
    }
}

根据您选择的数据结构,find步有很多选项。

答案 1 :(得分:3)

如果我必须在两个未排序的向量上执行此操作(没有库帮助),我想我会将一个元素中的所有元素添加到哈希表中,然后遍历第二个查找每个元素 - 应该比排序两者都更有效首先列出。

答案 2 :(得分:2)

int temp[5000]; // declare this globally if you're going to be 
                // doing a lot of set_intersection calls   

int main() {

  char x[]={'a','b','c','d','e'};
  char y[]={'b','c','g'};
  vector<char> v1(x,x+sizeof x/sizeof x[0]);
  vector<char> v2(y,y+sizeof y/sizeof y[0]);
  sort(v1.begin(),v1.end());
  sort(v2.begin(),v2.end());  // the vectors *must* be sorted!!!!!!

  vector<char> inter=vector<char>(temp,set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),temp)); // inter contains {'b','c'}
  int cnt=set_intersection(v1.begin(),v1.end(),v2.begin(),v2.end(),temp) - temp;    // cnt=2

  for(int i = 0; i < (int)inter.size(); ++i) {
    cout<<inter[i]<<" ";
  }
  cout<<endl;

  return 0;
}

答案 3 :(得分:1)

使用set_intersection。这是一个工作样本:

#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
    vector<string> v1;
    v1.push_back("Mary");
    v1.push_back("had");
    v1.push_back("a");

    vector<string> v2;
    v2.push_back("a");
    v2.push_back("little");
    v2.push_back("lamb");

    sort(v1.begin(), v1.end());
    sort(v2.begin(), v2.end());

    vector<string> v3;
    set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(), back_inserter(v3));

    copy(v3.begin(), v3.end(), ostream_iterator<string>(cout, "\r\n"));
    return 0;
}

答案 4 :(得分:1)

这并没有超出标准字符类型(可能是unicode,具体取决于应用程序),但是如果你有兴趣在O(n)时间内这样做,这应该可行。


#include <vector>
#include <string>
#include <iostream>

std::vector<char> intersect(const std::vector<bool>& x,
                            const std::vector<bool>& y)
{
    std::vector<char> rv;

    std::vector<bool>::const_iterator ix, iy;
    size_t i;

    for (i=0, ix = x.begin(), iy = y.begin();
         ix != x.end() && iy != y.end();
         ++i, ++ix, ++iy)
        if (*ix && *iy) rv.push_back( (char) i);

    return rv;
}

std::vector<bool> poll(const std::vector<char>& x)
{
    std::vector<bool> rv(256, false);

    for (std::vector<char>::const_iterator i = x.begin(); i != x.end(); ++i)
        rv[*i] = true;

    return rv;
}

std::vector<char> build(const std::string& val)
{
    std::vector<char> rv;

    for (size_t i = 0; i < val.size(); ++i)
        rv.push_back(val[i]);

    return rv;
}

int main(int argc, char *argv[])
{
    std::vector<char> x1 = build("The Quick Brown Fox Jumps Over The Lazy Dog");
    std::vector<char> x2 = build("Oh give me a home where the buffalo roam");

    std::vector<char> intersection = intersect(poll(x1), poll(x2));

    for (std::vector<char>::iterator i=intersection.begin();
            i != intersection.end(); ++i)
        std::cout << *i;

    std::cout << std::endl;

    return 0;
}

答案 5 :(得分:0)

因为事后证实你实际上只关心了26个字符:

std::bitset<26> in;
for (std::vector<char>::iterator it = first.begin(); it != first.end(); ++it) {
    in[*it - 'a'] = true;
}
for (std::vector<char>::iterator it = second.begin(); it != second.end(); ++it) {
    if (in[*it - 'a']) {
        result.push_back(*it);
        // this line is only needed if 'second' can contain duplicates
        in[*it - 'a'] = false;
    }
}

事实上,bitset<UCHAR_MAX>在几乎所有架构上都很小。请注意那些具有32位字符的DSP,并谨慎地将此技术应用于wchar_t

使用BOOST_FOREACH,代码甚至看起来合理:

assert(UCHAR_MAX <= 512 && "What kind of crazy machine is this?");
std::bitset<UCHAR_MAX> in;

BOOST_FOREACH(unsigned char c, first) {
    in[c] = true;
}

BOOST_FOREACH(unsigned char c, second) {
    if (in[c]) {
        result.push_back(c);
        // this line is only needed if 'second' can contain duplicates
        in[c] = false;
    }
}

答案 6 :(得分:-3)

如果你有字符,也许你应该使用std :: strings而不是vector?字符串具有足够的搜索功能等。