我有一个char指针数组(字符串数组),它包含一些重复的值。我发现了一种通过删除重复值来截断数组的算法。
以下是代码示例:
int i, j , k;
int n = 10;
char *teams[n];
for(i=0;i<n;i++){
for(j=i+1;j<n;){
if(*(team[j]==*(team[i])){
for(k=j;k<n;k++){
//strcpy(team[k], team[k+1]);
team[k] = team[k+1];
}
n--;
}else{
j++;
}
}
}
我读过在字符串数组之间复制字符串的唯一方法是使用strcpy(s1,s2)。但在我的情况下我不能使用它,因为只有当s2的长度等于或大于s1的长度时,strcpy函数才允许将s2复制到s1中。那么如果我不能把指针团队[k + 1]指向的字符串放在团队[k]中,我怎么能实现这个算法?
答案 0 :(得分:0)
#include <stdio.h>
#include <string.h>
unsigned dedup(char **arr, unsigned count)
{
unsigned this, that ;
for(this=0;this<count;this++){
for(that=this+1;that<count;){
if( strcmp(arr[that], arr[this])) {that++; continue; }
#if PRESERVE_ORDER
memmove(arr+that, arr+that+1, (--count - that) * sizeof arr[that] );
#else
arr[that] = arr[--count];
#endif
}
}
return count; /* the count after deduplication */
}
char *array[] = { "one", "two", "three", "two", "one", "four", "five", "two" };
int main(void)
{
unsigned count, index;
count = dedup(array, 8);
for (index = 0; index < count; index++) {
printf("%s\n", array[index] );
}
return 0;
}
[更新]:我添加了PRESERVE_ORDER版本
答案 1 :(得分:0)
似乎您需要删除重复的字符串表示而不是重复的地址到字符串。
如果是,那么这个if语句(如果要添加错过的闭括号)
for(k=j;k<n;k++){
//strcpy(team[k], team[k+1]);
team[k] = team[k+1];
}
只比较字符串的第一个字符,而不是比较指针指向的字符串。
在这个循环中
k
每次找到重复字符串时,都会复制整个指针数组。此外,当n-1
等于 team[k] = team[k+1];
^^^^
#include <stdio.h>
#include <string.h>
char ** unique( char *s[], size_t n )
{
size_t i = 0;
for ( size_t j = 0; j < n; j++ )
{
size_t k = 0;
while ( k < i && strcmp( s[k], s[j] ) != 0 ) ++k;
if ( k == i )
{
if ( i != j ) s[i] = s[j];
++i;
}
}
return s + i;
}
int main(void)
{
char * s[] = { "A", "B", "A", "C", "A" };
const size_t N = sizeof( s ) / sizeof( *s );
for ( size_t i = 0; i < N; i++ ) printf( "%s ", s[i] );
printf( "\n" );
char **p = unique( s, N );
size_t n = p - s;
for ( size_t i = 0; i < n; i++ ) printf( "%s ", s[i] );
printf( "\n" );
return 0;
}
您可以编写一个单独的函数来“删除”重复项。该函数可以例如在修改的数组中的最后一个唯一元素之后返回指针。
A B A C A
A B C
程序输出
{{1}}