将两个字符串中的相似性写入新动态数组的最简单方法

时间:2014-05-06 00:46:19

标签: c++ arrays function

我有一个函数,我想比较两个数组,找到匹配,然后创建第三个数组。该函数找到比较,但是当我尝试返回一个对象时,程序将中止。我最初的想法是,为c1.numMembers和c2.numMembers设置不同的值可能会导致我的循环出现故障。任何帮助表示赞赏。这就是我所拥有的。

Club mergeClubs(Club& c1, Club& c2)
{
    Club combined;
    combined.clubName = c1.clubName + "/" + c2.clubName;
    string* x = new string[combined.numMembers];
    for(int i = 0;i<c1.numMembers;i++)
    {
        for(int k =0;k<c2.numMembers;k++)
        {
            if(c1.members[i]==c2.members[k])
            {
                x[combined.numMembers] = c1.members[i];
                combined.numMembers++;
            }
        }
    }
    combined.members = x;


    return combined;
}

感谢所有答案。我理解使用向量会更简单,但我根本不允许更改有关初始类的任何内容,其中members *是我们必须在每种Club类型中使用的动态数组。我改变了我的代码,我有它所以最终的数组combined.members有正确的成员,但我仍然得到一个错误返回它。这是我的新代码。

Club mergeClubs(Club& c1, Club& c2)
{
//I changed the arrays to vectors to sort them and find the duplicates, then wrote     it back into an array. inefficient yes, but using vectors
//in the first place would have made the project 1000000000000x easier.
    Club combined(c1.clubName + "/" + c2.clubName);
    vector<string> x1;
    vector<string> x2;
    vector<string> combine;
    for(int i = 0;i<c1.numMembers;i++)
    {
        x1.push_back(c1.members[i]);
    }
    for(int i = 0;i<c2.numMembers;i++)
    {
        x2.push_back(c2.members[i]);
    }
    for(int i = 0;i<x1.size();i++)
    {
        for(int j = 0;j<x2.size();j++)
        {
            if(x1[i]==x2[j])
            {
                combine.push_back(x1[i]);
            }
        }
    }
    for(vector<string>::const_iterator i = combine.begin(); i != combine.end();     ++i)
    combined.numMembers = combine.size();
    combined.members = &combine[0];


    return combined;
 }

相信我,我知道这是多么低效。

2 个答案:

答案 0 :(得分:2)

您可能需要考虑为members字符串使用容器。例如,如果您使用std::set,则可以执行以下操作:

std::set<std::string> a, b, c;
// assume a and b contain some strings
std::set_intersection(
  a.begin(), a.end(),
  b.begin(), b.end(),
  std::inserter(c, c.end())
);

你也可以使用vector(或其他容器),你必须确保在创建交集之前已经sort


新代码的问题在于您将combined.members分配给指针,该指针在函数返回时将被删除(属于combine)。你仍然需要创建一个string的数组,并且如果你想要走这条路线的话就把它们从矢量中复制出来(大概是你在某个时候考虑过这个问题,但你的container上的循环并没有。似乎有用的任何目的。)

您仍然可以在原始指针上使用库算法,因此如果您无法更改结构,更好的解决方案可能类似于以下内容:

假设Club看起来像这样

struct Club
{
  std::string clubName;
  std::string* members;
  int numMembers;
};

Club mergeClubs(Club& c1, Club& c2)
{
  Club combined{
    c1.clubName + "/" + c2.clubName,
    new std::string[c1.numMembers + c2.numMembers],
    0
  };

  std::sort(c1.members, c1.members + c1.numMembers);
  std::sort(c2.members, c2.members + c2.numMembers); 

  auto end = std::set_intersection(
    c1.members, c1.members + c1.numMembers,
    c2.members, c2.members + c2.numMembers,
    combined.members
  );

  combined.numMembers = end - combined.members;

  return combined;
}

  

相信我,我知道这是多么低效。

它不仅仅关于效率,即使使用标准容器比处理数组慢,我仍然会选择代码顶部的代码(它通常不是,特别是如果你使用{ {1}} s),因为它更容易编写,阅读和维护。

答案 1 :(得分:1)

问题是您在定义字符串combined.numMembers之前使用x。不使用分配字符串数组,而是使用可扩展容器,例如std::vector<T>。使用std::vector<T>::append添加每个字符串。然后在最后,分配combined.members数组并从临时向量中复制每个字符串。