在C中查找字符串数组中的唯一元素

时间:2010-05-10 16:40:45

标签: 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
  }
}

但是当我对此进行编码时,结果很糟糕。(我处理了所有内存,小东西等)问题显然是在第二个循环中:D。但我想不出任何解决方案。如何在数组中找到唯一的字符串。

输入示例:输入abc def abe abc def deg 独特的:应该找到abc def abe deg。

5 个答案:

答案 0 :(得分:6)

您可以使用qsort强制重复项彼此相邻。排序后,您只需要比较相邻的条目以查找重复项。结果是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 );
  }

答案 1 :(得分:5)

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;
}

如果我这样做的话,每个唯一字符串第一次出现的索引应该是唯一的[0..n-1]。

答案 2 :(得分:2)

你为什么从1开始第二次循环?

你应该从中开始 I + 1。即。

for(j=i+1;j<20;j++) 

如果列表是

abc
def
abc
abc
lop

然后

当i == 4

TMP = “垂耳”

然后第二个循环从1到19开始。这意味着它在一个阶段也会获得4的值,然后

数据[4],即“lop”,将与tmp相同。因此,尽管“lop”是独一无二的,但它会被标记为重复。

希望它有用。

答案 3 :(得分:1)

更多地考虑一下你的问题 - 你真正想要做的是查看PREVIOUS字符串,看看你是否已经看过它。因此,对于每个字符串n,请将其与字符串0n-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

答案 4 :(得分:0)

可能是你的测试是(strcmp(this,that))如果两者不同会成功吗? !strcmp可能就是你想要的。