主题:删除整型数组中的重复数字
止止淮十
[专家分:0] 发布于 2010-11-30 11:56:00
#include <stdio.h>
#include <stdlib.h>
int main()
{
int i,j,k,a[20],n,count1=0,count2=0;
printf("Please input n:\n");
scanf("%d",&n);
printf("\n");
printf("input numbers:\n");
for(i=0;i<n;++i)
{ printf("请输入 :");
scanf("%d",&a[i]);
}
for(i=0;i<n;i++) if(a[i]==0) count1=1;
for(i=0;i<n;i++){
for(j=i+1;j<n;j++) {
if(a[j]==a[i]) a[j]=0;
}
}
for(i=0;i<n;i++){if(count2==0&&a[i]==0&&count1==1) {printf("%4d",a[i]); count2=1;}
else if(a[i]!=0) printf("%4d",a[i]);
}
printf("\n");
system("PAUSE");
return 0;
}
(运用的是DEV-C++4.9编译器)
上面程序运行无误
只望大家指正,提供更简便的方法
回复列表 (共7个回复)
沙发
lukexc [专家分:50] 发布于 2010-11-30 21:51:00
[code=c]
#include <stdio.h>
#define N 10
int main(void)
{
int a[N] = {0}, b[10] = {0}, i, j, k = 1;
printf("please Input %d numbers :\n" ,N);
for(i = 0; i < N; i ++)
{
scanf("%d" ,&a[i]);
for(j = 1; j < k; j ++)
if(a[i] == a[j - 1])a[i] = '\0';
k ++;
}
k = 0;
for(i = 0; i < N; i ++)
{
if('\0' == a[i]) k ++;
}
for(i = 0, j = 0; i < N, j < N - k; i ++)
{
if('\0' == a[i])continue;
else
{
b[j] = a[i];
printf("%d " ,b[j]);
j ++;
}
}
printf("\n");
return 0;
}[/code]
板凳
chubby_z [专家分:50] 发布于 2010-11-30 22:27:00
2楼似乎更复杂了,还引入了一个辅助存储空间
楼主写的似乎是最简洁直接的方法了,当然我是指遍历数组找重复那段
盼高人能写出高效率和高简洁的程式
3 楼
eastcowboy [专家分:25370] 发布于 2010-11-30 23:43:00
http://bbs.pfan.cn/post-357232.html
思路已经在这里说过了。
[code=c]#include <stdio.h>
int main()
{
int arr[100];
int i;
int n;
int input;
int count = 0;
scanf("%d", &n);
while (n--)
{
scanf("%d", &input);
for (i = 0; i < count && arr[i] != input; ++i)
{
}
if (i == count)
{
arr[count] = input;
++count;
}
}
for (i = 0; i < count; ++i)
{
printf("%d\n", arr[i]);
}
return 0;
}[/code]
4 楼
chubby_z [专家分:50] 发布于 2010-12-01 00:01:00
您是指您的思路?
若是这个数组不是输入的呢?
若是某种实际存在的数组,然后要求删除重复数字?
所以您还是没有解决到问题。
解决方法倒是有很多种,我有想过用排序,而且排序似乎在这种小量数据中反而在程序上更复杂。而且人家没要求排序。而且对于这种无序数据,遍历似乎是最简洁的。但是在时间度量上应该有更有效率的方法。
所以跪求最简洁,然后时间度量上也比较优的思路?(当然时间和空间上都最优怕是没有了)
在一篇“怎样生成1到6随机数?”中 bruceteen写的那个程序,真的让人折服,当然与解决当前帖子问题无关,
5 楼
eastcowboy [专家分:25370] 发布于 2010-12-01 23:11:00
这个要看楼主对简洁、简便怎么定义了。当然,如果一味追求代码段小的话,我觉得并不好。
如果您把问题看得更宽泛一些,其实从键盘输入和从数组中读取没什么不同,都是“获得一个整数”。程序稍微改改,把scanf换一下,基本上就成了。原来我的代码中,是从scanf到arr,总共只定义一个数组,如果生搬硬套,从数组输入,那就需要两个数组了。不过稍微改一改,一个数组也是可以做的:
[quote]#include <stdio.h>
int main() {
int arr[100];
int n;
int i, j, k;
// 输入
scanf("%d", &n);
for (i = 0; i < n; ++i)
{
scanf("%d", &arr[i]);
}
// 删除重复的数。
// 变量i表示当前处理第i个输入的元素
// 变量j表示处理之后,剩余的元素个数(相同的元素被剔除)
// 变量k用于循环,检查之前这个元素是否出现
j = 0;
for (i = 0; i < n; ++i)
{
for (k = 0; k < j && arr[i] != arr[k]; ++ k)
{
}
if (k == j)
{
arr[j] = arr[i];
++j;
}
}
// 输出
for (i = 0; i < j; ++i)
{
printf("%d\n", arr[i]);
}
return 0;
}[/quote]
整个程序除了本身需要保存输入的内容之外,不再需要数组了。变量个数、for循环的个数都比楼主最初的代码有所减少。
不过这个程序破坏了输入。一旦执行完毕,arr里面的内容已经不是最初输入的内容了。要修改也容易,在那个if里面输出就行,最后的for循环输出就不要了。
上面这样的做法比较节省内存,但运行时间方面,表现就不够了。(时间复杂度是平方级的)
其实主要是在查找方面比较花时间,因此可以花费一些内存,建立有效的存储结构,以便实施快速查找。这样做可以提高运行速度,但是花费了内存,而且程序会变得复杂一些。
如果允许排序,那就先排序,然后挨个把相邻且重复的元素去掉(C++提供了一个函数来完成这项工作,它的名字是std::unique)。这样做速度快,而且不复杂,并且也不用另外耗费太多内存。但这个方法也有问题,那就是输出的顺序与输入的顺序不一致。
6 楼
windy0will [专家分:2300] 发布于 2010-12-05 16:20:00
[quote]在一篇“怎样生成1到6随机数?”中 bruceteen写的那个程序,真的让人折服[/quote]
每次看到bruceteen,eastcowboy两位神级别的高手的代码,我总是细细的品读与吸收,总想趁机偷学个一招半式。
7 楼
luotuo44 [专家分:0] 发布于 2010-12-12 20:21:00
修改了一下
#include <stdio.h>
#include <stdlib.h>
#include<malloc.h>
int main()
{
int i, j, *a, n, count1=0;
printf("Please input n:\n");
scanf("%d",&n);
printf("\n");
a=(int *)malloc(n*sizeof(int));
printf("input numbers:\n");
for(i=0;i<n;++i)
{
printf("请输入 :");
scanf("%d",&a[i]);
if(a[i]==0)
{
count1=1;
}
}
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(a[j]==a[i]) a[j]=0;
}
}
for(i=0;i<n;i++)
{
if(a[i]!=0)
{
printf("%4d",a[i]);
}
else if( count1 == 1 )
{
printf("0");
count1= 2;
}
}
printf("\n");
system("PAUSE");
return 0;
}
我来回复