在C中查找字符串数组中的唯一元素
C对字符串的处理让我很烦恼。我脑子里有这样一个伪代码:在C中查找字符串数组中的唯一元素,c,arrays,string,strcmp,C,Arrays,String,Strcmp,C对字符串的处理让我很烦恼。我脑子里有这样一个伪代码: char *data[20]; char *tmp; int i,j; for(i=0;i<20;i++) { tmp = data[i]; for(j=1;j<20;j++) { if(strcmp(tmp,data[j])) //then except the uniqueness, store them in elsewhere } } char*数据[20]; char*t
char *data[20];
char *tmp; int i,j;
for(i=0;i<20;i++) {
tmp = data[i];
for(j=1;j<20;j++)
{
if(strcmp(tmp,data[j]))
//then except the uniqueness, store them in elsewhere
}
}
char*数据[20];
char*tmp;int i,j;
对于(i=0;i您可以使用强制将重复项彼此相邻。排序后,您只需比较相邻项以查找重复项。结果是O(N log N),而不是(我认为)O(N^2)
以下是15分钟午餐时间版本,无错误检查:
typedef struct {
int origpos;
char *value;
} SORT;
int qcmp(const void *x, const void *y) {
int res = strcmp( ((SORT*)x)->value, ((SORT*)y)->value );
if ( res != 0 )
return res;
else
// they are equal - use original position as tie breaker
return ( ((SORT*)x)->origpos - ((SORT*)y)->origpos );
}
int main( int argc, char* argv[] )
{
SORT *sorted;
char **orig;
int i;
int num = argc - 1;
orig = malloc( sizeof( char* ) * ( num ));
sorted = malloc( sizeof( SORT ) * ( num ));
for ( i = 0; i < num; i++ ) {
orig[i] = argv[i + 1];
sorted[i].value = argv[i + 1];
sorted[i].origpos = i;
}
qsort( sorted, num, sizeof( SORT ), qcmp );
// remove the dups (sorting left relative position same for dups)
for ( i = 0; i < num - 1; i++ ) {
if ( !strcmp( sorted[i].value, sorted[i+1].value ))
// clear the duplicate entry however you see fit
orig[sorted[i+1].origpos] = NULL; // or free it if dynamic mem
}
// print them without dups in original order
for ( i = 0; i < num; i++ )
if ( orig[i] )
printf( "%s ", orig[i] );
free( orig );
free( sorted );
}
typedef结构{
国际原版;
字符*值;
}分类;
int qcmp(常数无效*x,常数无效*y){
int res=strcmp((排序*)x)->值,((排序*)y)->值;
如果(res!=0)
返回res;
其他的
//他们是平等的-使用原始位置作为领带断路器
返回(((SORT*)x)->origpos-((SORT*)y)->origpos;
}
int main(int argc,char*argv[])
{
排序*已排序;
原稿;
int i;
int num=argc-1;
orig=malloc(sizeof(char*)*(num));
排序=malloc(sizeof(SORT)*(num));
对于(i=0;i
是否您的测试是if(strcmp(this,that)),如果两者不同,哪个测试会成功?!strcmp可能就是您想要的结果。char*data[20];
char *data[20];
int i, j, n, unique[20];
n = 0;
for (i = 0; i < 20; ++i)
{
for (j = 0; j < n; ++j)
{
if (!strcmp(data[i], data[unique[j]]))
break;
}
if (j == n)
unique[n++] = i;
}
inti,j,n,unique[20];
n=0;
对于(i=0;i<20;++i)
{
对于(j=0;j
如果我做得对,每个唯一字符串第一次出现的索引应该是唯一的[0..n-1]。为什么要从1开始第二个循环
你应该从头开始
i+1,即
for(j=i+1;j<20;j++)
然后
当i==4时
tmp=“lop”
但是第二个循环开始,从1到19。这意味着它在一个阶段也会得到一个值4,然后
数据[4],即“lop”,将与tmp相同。因此,虽然“lop”是唯一的,但它将被标记为重复
希望对您有所帮助。仔细想想您的问题--您真正想做的是查看前面的字符串,看看您是否已经看到了它。因此,对于每个字符串n
,将其与字符串0
通过n-1
进行比较
print element 0 (it is unique)
for i = 1 to n
unique = 1
for j = 0 to i-1 (compare this element to the ones preceding it)
if element[i] == element[j]
unique = 0
break from loop
if unique, print element i
首先对数组进行排序会有很大的帮助。然后只需对字符串进行迭代,如果当前字符串与前一个字符串不同,则它是唯一的,您可以将其存储在其他位置。问题是我需要确切的位置。您知道这样的情况:输入:abc def abe abc def deg输入唯一的值:abc def abe deg如果我对数组进行排序我会得到这样独特的:abc abe def deg这不是我想要的,我还需要位置。然后在你排序的初始数组中创建一个指针数组或数组索引数组,而不是对初始数组进行排序。他也可以尝试构建一个哈希表,尽管只有20个左右的项目,这肯定是多余的。我知道这一点。我不想要排序的数组,也不想做这项工作。我需要这些带有位置的数组。你知道这样的:输入:abc def abe abc def deg输入唯一的数组:abc def abe deg如果我对数组排序,我会得到唯一的数组:abc abe def deg这不是我想要的,我也需要位置。我想Mark不知道,行动吧实际上,因为你在问题中没有提到这一点。这就是为什么我要问这个:)。我已经知道排序和检查相邻元素。但这并不能解决我的问题。按照WhirlWind的建议对指数数组进行排序应该可以解决这个问题。它会保持原来的订单不变。这看起来很有趣,我会试试这个。这绝对不是主要问题。仍然是O(n^2),这取决于你对“主要问题”的定义。这个答案确定了一个正确性问题,它比性能问题更严重。@caf和@Terry:实际上,在他的问题中,我没有发现任何与性能相关的东西。他的话是:“但是当我编写这个代码时,结果很糟糕。(我处理了所有的内存、小事情等)。问题显然在第二个循环中:D。但我想不出任何解决方案。我如何在数组中找到唯一的字符串。”所以我只关注了为什么他的代码不起作用。后来,从其他答案和评论中,我意识到讨论的形式有所不同。
print element 0 (it is unique)
for i = 1 to n
unique = 1
for j = 0 to i-1 (compare this element to the ones preceding it)
if element[i] == element[j]
unique = 0
break from loop
if unique, print element i