从指针数组C中删除重复的元素
我正在尝试接受用户输入并在单独的一行上打印每个单词(没有重复)。到目前为止,我所做的是能够接受用户输入并按字母顺序分别打印每一行。我现在需要做的是能够删除char*argue[]数组中的重复项 我的意见:从指针数组C中删除重复的元素,c,arrays,pointers,C,Arrays,Pointers,我正在尝试接受用户输入并在单独的一行上打印每个单词(没有重复)。到目前为止,我所做的是能够接受用户输入并按字母顺序分别打印每一行。我现在需要做的是能够删除char*argue[]数组中的重复项 我的意见: ./a.out banana apple apple apple zoo cat fork 我的输出: apple apple apple banana cat fork zoo 需要做的是打印一个苹果而不是三个 以下是我到目前为止所做的工作,我已经对代码中存在问题的部分进行了注释 #in
./a.out banana apple apple apple zoo cat fork
我的输出:
apple
apple
apple
banana
cat
fork
zoo
需要做的是打印一个苹果而不是三个
以下是我到目前为止所做的工作,我已经对代码中存在问题的部分进行了注释
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[]) {
int i, j, k, size;
size = argc -1;
char *key;
char* a[argc-1];
for (i = 2; i < argc; i++) {
key = argv[i];
j = i-1;
while (j >= 1 && strcmp(argv[j], key) > 0) {
argv[j+1] = argv[j];
j--;
}
argv[j+1] = key;
}
//Problem
//for(i = 2; i < size; i++){
// if(argv[i-1] != argv[i])
// a[i] = argv[i-1];
//}
//for(i=0; i< size; i++)
// puts(a[i]);
for(i=1; i< argc; i++)
puts(argv[i]);
return 0;
}
#包括
#包括
int main(int argc,char*argv[]){
int i,j,k,大小;
尺寸=argc-1;
字符*键;
字符*a[argc-1];
对于(i=2;i=1&&strcmp(argv[j],键)>0){
argv[j+1]=argv[j];
j--;
}
argv[j+1]=键;
}
//问题
//对于(i=2;i
首先,您可以使用标题
中声明的标准C函数qsort
如果要输出不包含重复项的参数,则无需删除参数。您可以只输出唯一的参数
程序可以按以下方式运行
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int cmp(const void *left, const void *right)
{
return strcmp(*(const char **)left, *(const char **)right);
}
int main( int argc, char * argv[] )
{
if (argc > 1)
{
qsort(argv + 1, argc - 1, sizeof(*argv), cmp);
for (int i = 1; i < argc; )
{
puts(argv[i]);
while (argv[++i] != NULL &&
strcmp(argv[i - 1], argv[i] ) == 0);
}
}
return 0;
}
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int cmp(const void *left, const void *right)
{
return strcmp(*(const char **)left, *(const char **)right);
}
int main( int argc, char * argv[] )
{
if (argc > 1)
{
qsort(argv + 1, argc - 1, sizeof(*argv), cmp);
int n = 1;
for (int i = 1; i < argc; i++)
{
int j = 1;
while (j < n && strcmp(argv[j], argv[i]) != 0) j++;
if (j == n)
{
if (n != i) argv[n] = argv[i];
++n;
}
}
argc = n;
argv[argc] = NULL;
}
for ( int i = 1; i < argc; i++ ) puts(argv[i]);
return 0;
}
然后程序输出将如下所示
apple
banana
cat
fork
zoo
如果确实要“删除”重复的参数,则argc
应具有相对于修改后的参数列表的正确值,argv[argc]
应等于NULL
程序可以按以下方式运行
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int cmp(const void *left, const void *right)
{
return strcmp(*(const char **)left, *(const char **)right);
}
int main( int argc, char * argv[] )
{
if (argc > 1)
{
qsort(argv + 1, argc - 1, sizeof(*argv), cmp);
for (int i = 1; i < argc; )
{
puts(argv[i]);
while (argv[++i] != NULL &&
strcmp(argv[i - 1], argv[i] ) == 0);
}
}
return 0;
}
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int cmp(const void *left, const void *right)
{
return strcmp(*(const char **)left, *(const char **)right);
}
int main( int argc, char * argv[] )
{
if (argc > 1)
{
qsort(argv + 1, argc - 1, sizeof(*argv), cmp);
int n = 1;
for (int i = 1; i < argc; i++)
{
int j = 1;
while (j < n && strcmp(argv[j], argv[i]) != 0) j++;
if (j == n)
{
if (n != i) argv[n] = argv[i];
++n;
}
}
argc = n;
argv[argc] = NULL;
}
for ( int i = 1; i < argc; i++ ) puts(argv[i]);
return 0;
}
#包括
#包括
#包括
int cmp(常数无效*左,常数无效*右)
{
返回strcmp(*(常量字符**)左,*(常量字符**)右);
}
int main(int argc,char*argv[])
{
如果(argc>1)
{
qsort(argv+1,argc-1,sizeof(*argv),cmp);
int n=1;
对于(int i=1;i
它的输出将与上面显示的相同。在C中,字符串本身不是数据类型,而是语言引入的约定。记住这一点很重要 现在,如果有两个字符指针,那么即使它们指向的字符串相同,它们存储的地址也可能不相同。那么,比较呢
if (argv[i-1] != argv[i])
不会检查字符串是否相同,而是只比较地址。因此:
char * a = "Hello world!\n";
char * b = a;
if (a == b) {
puts("Always true\n");
}
因为在这里,您实际上并没有复制字符串,您只是复制存储字符串的地址。这也产生了这样的效果:
char a[20] = "Hello world!\n";
char * b = a;
a[0] = 'X';
puts(b); // Will print "Xello world!\n";
所以,您需要的是某种方法来比较这两个变量所指向的字符串。这就是strcmp的作用。如果字符串相同,则返回0
;如果第一个字符串按字母顺序在第二个字符串之前或之后,则返回-1
或+1
所以使用测试
if (!strcmp(argv[i-1], argv[i]))
所有这些都应该像预期的那样起作用。请记住,数组a
不包含字符串的副本,而是只指向argv中的字符串
/编辑:事实上,还有一些小错误,但一旦这个问题解决了,我想你也可以修复其余的
==评论中暗示的建议===
在这样的代码中:
for (i = 2; i < size; i++) {
if (argv[i-1] != argv[i])
a[i] = argv[i-1];
}
for(i=2;i
通过添加这样的行,您很容易出错:
for (i = 2; i < size; i++) {
if (argv[i-1] != argv[i])
printf("argv[%i] and argv[%i] are identical\n", i-1, i);
a[i] = argv[i-1];
}
for(i=2;i
因为在那里,您可能会忘记添加另一个卷曲制动。因此,我建议始终添加它,即使对于这样的一行:
for (i = 2; i < size; i++) {
if (argv[i-1] != argv[i]) {
a[i] = argv[i-1];
}
}
for(i=2;i
指针比较与字符串比较不一样。这是有说明的,但对OP没有帮助,他显然在学习C,应该理解字符串和指针的概念。这个答案对他没有帮助。从char*中删除或只是使用另一个数组并不重要。只要重复项消失@arkadiyth,这是一个很好的解决方案,我真的不明白while循环在for循环中是如何工作的。我很困惑,为什么它会以失败告终;而且没有条件。解释一下就好了。谢谢!:)@首先,正如我在回答中所写,argv[argc]应该等于null。while循环有一个条件,但它的bod是空语句