在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

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*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