问题:随机生成n (n < 100 000)个0到999之间的整数,可能有重复的整数,从小到大输出这些整数(忽略重复数字)。例如,假设n=8,随机生成8个数是:
1 2 5 2 4 5 6 2
输出结果为:
1 2 4 5 6
解题方法1:先排序,在去重
#include<stdio.h>
#include <math.h>
#define N 20
void InPutArr(int array[], int n);
void sort(int array[], int n);
void PrintArr (int array[], int n);
int main()
{
int n,a[N] = {0};
printf("输入整数个数:\n");
scanf("%d",&n);
// 输入数组a的n个元素
InPutArr(a,n);
// 将数组array的n个元素升序排序
sort(a,n);
printf("排序后数组为:\n");
// 去重并输出数组的n个元素
PrintArr(a,n);
return 0;
}
//读入n个整数存入数组array
void InPutArr(int array[], int n)
{
int i;
printf("输入%d个整数:\n",n);
for(i = 0; i <n; i++)
{
scanf("%d",&array[i]);
}
}
//将数组array中的元素进行升序排序
void sort(int array[] , int n)
{
int i,j,t;
for(i = 0; i < n-1; i++)
{
for (j = i+1; j < n; j++ )
{
if(array[i] > array[j])
{
t = array[i]; array[i] = array[j]; array[j] = t;
}
}
}
}
//输出数组array的n个元素
void PrintArr(int array[], int n)
{
int i;
for(i = 0;i < n; i++)
{
if(i == 0)
printf("%d",array[i]);
else
if(array[i] != array[i-1])
printf("% d",array[i]);/**<去重处理( 若a[i]不同于前一个相邻元素,则输出a[i] )*/
}
printf("\n");
}
运行结果:
解题方法2:用元素a[i]记录器对应下标i的出现次数
因为n的取值范围较大:[1, 100 000],故使用排序代价较大,而当n个整数的取值范围较小时:[0, 999],可以使用一个长度是1000的数组a保存与数组下标对应元素出现的次数,当数字 i 每出现一次,a[i] 的值就加1。比如输入以下整数:
1 2 5 2 4 5 6 5 2
因为数字0没有出现,所以使a[0]=0; 数字1出现一次,a[1]=1; 数字2出现了3次,a[2]=3;3没有出现,a[3]=0......
数字出现次数 | 0 | 1 | 3 | 0 | 1 | 3 | 1 | 0 | 0 | ... |
数组下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ... |
最后扫描数组,输出所有非0元素对应的下标,就能得到排序结果:
1 2 4 5 6
代码如下:
#include<stdio.h>
#include <math.h>
#define N 1000
void PrintIndex(int array[]);
int main()
{
int n,num;
int a[N] = {0}; /**< 初始化数组 */
printf("请输入整数个数:\n");
scanf("%d",&n);
printf("请输入%d个整数:\n",n);
while(n--)
{
scanf("%d",&num);/**< 读入一个整数num */
a[num] ++; /**< 用a[num]记录num出现的次数*/
}
PrintIndex(a); /**< 去重并输出 */
return 0;
}
//输出a中非0元素对应的下标
void PrintIndex (int array[])
{
int i;
for(i = 0;i < N; i++)
{
if(array[i] > 0)
printf("%d ", i);
}
printf("\n");
}
运行结果:
注意:不要忘记初始化数组,注意数组长度范围,防止下标越界。