明明的随机数(四种数组去重方法)

目录

前言

一、暴力去重 + 冒泡排序

二、利用冒泡排序的结果进行去重

三、使用双指针对有序数组进行去重

四、特殊解法(有局限性)



前言

题目描述:明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数(N <= 100),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成"去重"与"排序"的工作。

题目链接:[P1059 NOIP2006 普及组] 明明的随机数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

一、暴力去重 + 冒泡排序

#include <stdio.h>

#define N 100

void bubble_sort(int arr[], int n)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < n - 1; i++)
	{
		int flag = 1;  // 假设 arr 已经有序
		for (j = 0; j < n - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 0;
			}
		}
		if (flag)
		{
			break;
		}
	}
}

int main()
{
	int arr[N] = { 0 };
	int n = 0;
	// 输入
	scanf("%d", &n);
	int i = 0;
	for (i = 0; i < n; i++)
	{
		scanf("%d", &arr[i]);
	}
	// 暴力去重
	int j = 0;
	int k = 0;
	for (i = 0; i < n; i++)
	{
		for (j = i + 1; j < n; j++)
		{
			if (arr[j] == arr[i])
			{
				for (k = j; k < n - 1; k++)  // 将 arr[j] 后面的元素往前挪一个位置
				{
					arr[k] = arr[k + 1];
				}
				j--;  // 原来 arr[j + 1] 的元素变成了 arr[j],避免漏掉重复的元素,所以让 j 减 1
				n--;  // 去掉重复的数字
			}
		}
	}
	// 排序(冒泡排序)
	bubble_sort(arr, n); 
	// 输出
	printf("%d\n", n);
	for (i = 0; i < n; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

二、利用冒泡排序的结果进行去重

#include <stdio.h>

#define N 100

void bubble_sort(int arr[], int n)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < n - 1; i++)
	{
		int flag = 1;  // 假设 arr 已经有序
		for (j = 0; j < n - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 0;
			}
		}
		if (flag)
		{
			break;
		}
	}
}

int main()
{
	int arr[N] = { 0 };
	int n = 0;
	// 输入
	scanf("%d", &n);
	int i = 0;
	for (i = 0; i < n; i++)
	{
		scanf("%d", &arr[i]);
	}
	// 排序(冒泡排序)
	bubble_sort(arr, n);
	// 去重
	for (i = 0; i < n - 1; i++)
	{
		if (arr[i] == arr[i + 1])
		{
			int j = 0;
			for (j = i; j < n - 1; j++)
			{
				arr[j] = arr[j + 1];
			}
			i--;
			n--;
		}
	}
	// 输出
	printf("%d\n", n);
	for (i = 0; i < n; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

三、使用双指针对有序数组进行去重

#include <stdio.h>

#define N 100

void bubble_sort(int arr[], int n)
{
	int i = 0;
	int j = 0;
	for (i = 0; i < n - 1; i++)
	{
		int flag = 1;  // 假设 arr 已经有序
		for (j = 0; j < n - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 0;
			}
		}
		if (flag)
		{
			break;
		}
	}
}

int main()
{
	int arr[N] = { 0 };
	int n = 0;
	// 输入
	scanf("%d", &n);
	int i = 0;
	for (i = 0; i < n; i++)
	{
		scanf("%d", &arr[i]);
	}
	// 排序(冒泡排序)
	bubble_sort(arr, n);
	// 使用双指针去重
	int slow = 0;
	int fast = 1;
	for (fast = 1; fast < n; fast++)
	{
		if (arr[slow] != arr[fast])
		{
			arr[++slow] = arr[fast];
		}
	}
	// 输出
	n = slow + 1;
	printf("%d\n", n);
	for (i = 0; i < n; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	return 0;
}

算法思路(前提是数组已经有序)

  1. 将 slow 和 fast 分别初始化为 0 和 1。

  2. 不断地增加 fast,直到 slow 的内容和 fast 的内容不相等,此时 slow 到 fast - 1 的元素重复,于是把 fast 的内容赋值给 ++slow。

  3. 重复第 2 步,直到 fast 到达尽头。

  4. 当整个循环结束后,slow + 1 即当前删除重复元素后的数组长度。

示例

 

四、特殊解法(有局限性)

#include <stdio.h>

#define MAX 1000  // 随机数的最大值

int main()
{
	int arr[MAX + 1] = { 0 };
	int n = 0;
	scanf("%d", &n);
	int count = 0;
	int tmp = 0;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		scanf("%d", &tmp);
		if (arr[tmp] == 0)
		{
			count++;
			arr[tmp] = tmp;
		}
	}
	// 输出
	printf("%d\n", count);
	for (i = 1; i < MAX + 1; i++)
	{
		if (arr[i] != 0)
		{
			printf("%d ", arr[i]);
		}
	}
	printf("\n");
	return 0;
}
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值