你有一个C代码,其中我有一个2D char数组 -
names[100][20] //Currently maximum 100 names, each of 19 characters supported
这个数组被一些带有名字的逻辑填充。我在变量names_found中跟踪实际找到的名字总数(可能少于100个名字)。
现在我要删除可能存在的重复名称。我打算做的事就是这样。
for(i=0;i<names_found;i++)
{
for(j=i+1;j<names_found;j++)
{
//Then compare(strcmp) each string/name with every other.
//e.g. if there were 4 names the comparisons done would be
//{name[0],name[1]},{name[0],name[2]},{name[0],name[3]}
//{name[1],name[2]} , {name[1],name[3]}
//& {name[2],name[3]}
//And then some more logic to remove duplicate based on result of strcmp results. Don't know what this logic would look like to store the result in place, in same 2D character buffer?
}
}
这是重复删除单词的逻辑,我在做什么是正确的,功能性的?
如何优化速度。
任何更好/更快的解决方案。
答案 0 :(得分:1)
有更快的方法和方法可以做到这一点,但不一定适用于这么小的一套。另外,你删除名字的逻辑可能比你想象的要花费更长的时间,因为它会导致你必须解决的数组中的空白,或者你需要将你的答案memmove()回来填补空白。
关闭Boyer-Moore类型的搜索可能会加快速度,但是根据strcmp函数的速度,你可能无法从中获得任何好处,因为设置查找的开销等等。如果你设置正确,你可以使用strstr()代替你的搜索,这可能会使用更高级的搜索算法。
基本上,你的集合太小了,以至于优化可能有点为时过早。
答案 1 :(得分:1)
这是一种简单的方法。它假定名称的顺序并不重要:
for (i = 0; i < names_found; i ++)
{
j = i + 1;
while (j < names_found)
{
if (strcmp(names[i], names[j]) == 0)
{
memmove(names + j, names + (names_found - 1), sizeof(names[0]));
-- names_found;
}
else
++ j;
}
}
答案 2 :(得分:0)
逻辑上没问题:对于每个数组元素,搜索以下元素中是否存在其他元素,如果是,则删除它们;但是你需要动态改变数组大小;例如如果删除第一个元素的3个副本,则剩余的元素数小于names_found
,因此您需要相应地更新它。
如果对数组进行排序(使用快速排序算法,但可能取决于数据的大小),则可以使其更快,然后重复都是“并排”。使用目标数组会更快,因为如果找到N个重复项,则不需要将所有其他数组元素移回N个位置(在最坏的情况下,您需要一个与源数组大小相同的数组)。
另一种方法是使用哈希容器;在这种情况下,你需要一个库(例如glib有一个哈希表“对象”),你的代码看起来会有所不同(例如,你可以在填充哈希表时“跳过”重复项。)