Bootstrap

牛客网刷题小结---C语言---有序序列(详解)

❤❤❤本篇是详解版❤❤❤

💖💖💖文章较长建议收藏学习💖💖💖

1.有序序列的判断

2.有序序列插入一个数字

3.序列中删除指定数字

4.序列中整数去重

5.有序序列的合并

1.有序序列的判断(✔ / ×)🤔

题目描述

输入一个整数序列,判断是否是有序序列。有序,指序列中的整数从小到大排列或者从大到小排序。

输入描述:

第一行输入一个整数 N (3 <= N <=50)。

第二行输入 N 个整数,用空格分隔 N 个整数。

输出描述:

输出为一行,若有序则输出" 有序 ",否则输出'' 无序 ''。

题目分析:

1.判断序列是否有序有两种情况,升序或者降序,并且只能满足一种情况. 我们可以先假设整个序列既有升序又有降序为真,经过遍历以后再判断是否有序。

	int flag1 = 1;//升序有序
	int flag2 = 1;//降序有序
//...
//遍历,判断是升序还是降序(在该过程对flag1 或 flag2的值进行修改)
//...
	if (flag1 + flag2 == 1)//判断序列是否有序
	{
		printf("序列有序");
	}
	else
	{
		printf("序列无序");
	}

2.通过对序列进行遍历来判断序列是升序还是降序,进而确定是否有序。

	//判断是否有序
	for (i = 0;i < n - 1;i++)
	{
		//判断是否升序
		if (arr[i] >= arr[i + 1])
		{
			flag1 = 0;//不是升序
		}
		//判断是否降序
		if (arr[i] < arr[i + 1])
		{
			flag2 = 0;
		}

3.最后对两个部分进行整合。

//有序序列的判断
#include<stdio.h>
int main()
{
	int n = 0;
	int arr[50] = { 0 };
	int flag1 = 1;//升序有序
	int flag2 = 1;//降序有序
	printf("请输入数组大小:\n");
	scanf("%d", &n);
	int i = 0;
	printf("请依次输入数组元素:\n");
	for (i = 0;i < n;i++)
	{
		scanf("%d", &arr[i]);
	}
	//判断是否有序
	for (i = 0;i < n - 1;i++)
	{
		//判断是否升序
		if (arr[i] >= arr[i + 1])
		{
			flag1 = 0;//不是升序
		}
		//判断是否降序
		if (arr[i] < arr[i + 1])
		{
			flag2 = 0;
		}
	}
	if (flag1 + flag2 == 1)
	{
		printf("序列有序");
	}
	else
	{
		printf("序列无序");
	}
	return 0;
}

运行结果:

2.有序序列 👉插入👈 一个数字

题目描述

有一个有序数字序列,从小到大排序,将一个新输入的数插入到序列中,保证插入新数后,序列仍然是升序。

输入描述:

第一行输入一个整数(0<=N<=50)。

第二行输入 N 个升序排列的整数,输入用空格分隔的 N 个整数。

第三行输入想要插入的一个整数。

输出描述:

输出为一行, N +1个有序排列的整数。

题目分析:

1.该题中最核心的问题是如何正确的插入元素,从而保证整个序列仍然是有序的。我们可以从整个序列的最右端(数值最大端)开始,用要插入的元素和序列中的各个元素依次进行比较,并进行交替替换直到最后一个元素。

参考代码:

//插入,假设要插入的变量为 m 
    //从数组的最右端开始,使用 if 当 i 等于-1时插入或者直接令 i 大于-1
	for (i = n - 1;i >= -1;i--)
	{
		if (arr[i] > m)//用要插入的元素和序列中的各个元素依次进行比较,并进行交替替换
		{
			arr[i + 1] = arr[i];
		}
		else//找到了正确的位置,直接插入
		{
			arr[i + 1] = m;
			break;
		}
	}//直到遍历到最后一个元素,插入
	if (i == -1)
	{
		arr[0] = m;
	}

2.完善整个过程

//有序序列插入一个数字
#include<stdio.h>
int main()
{
	int n = 0;
	//arr是数组
	int arr[20] = { 0 };//数组大小不要超过20,防止越界
	int m = 0;//要插入的元素
	//输入
	printf("请输入数组元素的个数 n :\n");
	scanf("%d", &n);
	int i = 0;
	printf("请依次输入 n 个升序排列的整数:\n");
	for (i = 0;i < n;i++)
	{
		scanf("%d", &arr[i]);
	}
	printf("请输入要插入的数字:\n");
	scanf("%d", &m);
	插入
	for (i = n - 1;i >= -1;i--)//使用 if 当 i 等于-1时插入或者直接令 i 大于-1
	{
		if (arr[i] > m)//用要插入的元素和序列中的各个元素依次进行比较,并进行交替替换
		{
			arr[i + 1] = arr[i];
		}
		else//找到了正确的位置,直接插入
		{
			arr[i + 1] = m;
			break;
		}
	}
	if (i == -1)//直到遍历到最后一个元素,插入
	{
		arr[0] = m;
	}
	//输出
	for (i = 0;i < n + 1;i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:

3.序列中❌删除❌指定数字

题目描述:

有一个整数序列(可能有重复的整数),现删除指定的某一个整数,输出删除指定数字之后的序列,序列中未被删除的数字前后位置没有发生改变。

输入描述:

第一行输入一个整数(0 <= N <=50)

第二行输入 N 个整数,输入用空格分隔的 N 个整数。

第三行输入想要删除的一个整数。

输出描述:

输出为一行,删除指定数字之后的序列。

题目分析:

1.该题中的核心问题在于如何找到指定数字并删除。找到指定数字我们可以通过 for() 循环 和 if() 语句来完成,而删除指定数字我们可以采用替换(也可以称之为覆盖)的方法。

//我们假定要删除的数字是 m 
for (i = 0;i < n;i++)//对数组进行遍历
	{
		if (arr[i] != m)//判断是否为要删除的数字。
		{
			arr[j++] = arr[i];//若不是依次向前推进,若是则对其进行覆盖
		}
	}

2.完善整个过程,需要注意的是最后整个数组元素个数的变化,遍历的过程也对数组元素的个数进行了修改。

//序列中删除指定数字
#include<stdio.h>
int main()//原理:替换
{
	int n = 0;
	int arr[50] = { 0 };
	int m = 0;
	//输入数据
	printf("请输入数组大小:\n");
	scanf("%d", &n);
	int i = 0;
	int j = 0;
	printf("请依次输入数组元素:\n");
	for (i = 0;i < n;i++)
	{
		scanf("%d", &arr[i]);
	}
	printf("请输入要删除的元素:\n");
	scanf("%d", &m);
	for (i = 0;i < n;i++)//对数组进行遍历
	{
		if (arr[i] != m)//判断是否为要删除的数字
		{
			arr[j++] = arr[i];//若不是依次向前推进,若是则对其进行覆盖
		}
	}
	for (i = 0;i < j;i++)//注意,遍历的过程也对数组元素的个数进行了修改
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:

 4.序列中整数去重(✂🎁🎁🎁)

题目描述:

输入 n 个整数的序列,要求对这个序列进行去重操作。所谓去重是指对这个序列中的每个重复出现的整数,只保留该数第一次出现的位置,删除其余位置。

输入描述:

输入包含两行,第一行包含一个正整数 n(1<=  n <= 1000),表示第二行序列中数字的个数;第二行包含 n 个整数(范围1~5000),用空格分隔。

输出描述:

输出为一行,按照输入的顺序输出去重之后的数字,用空格分隔。

题目分析:

1.该题中的重点是如何对数组进行去重操作。我们这里采用前后覆盖的方法,对两个前后相邻的两个元素进行比较,若相等则后一个元素将前一个元素覆盖掉,并且同时对覆盖之后的数组元素个数对应的下标进行修改。

	//去重
	for (i = 0;i < n;i++)
	{
		int j = 0;
		for (j = i + 1;j < n;j++)
		{
			if (arr[i] == arr[j])//判断两个前后相邻的元素是否重叠
			{
				//把下表为 j 的位置覆盖掉
				int k = 0;
				for (k = j;k < n - 1;k++)
				{
					arr[k] = arr[k + 1];
				}
				n--;//修改去重后元素个数以及坐标的变化
				j--;
			}
		}
	}

2.完善整个程序。

//整数去重,覆盖法,不会受到范围的限制
#include<stdio.h>
int main()
{
	int n = 0;
	int arr[100] = { 0 };
	//输入
	printf("请输入数组大小:\n");
	scanf("%d", &n);
	int i = 0;
	printf("请依次输入数组元素:\n");
	for (i = 0;i < n;i++)
	{
		scanf("%d", &arr[i]);
	}
	//去重
	for (i = 0;i < n;i++)
	{
		int j = 0;
		for (j = i + 1;j < n;j++)
		{
			if (arr[i] == arr[j])//判断前后两个相邻的元素是否有重叠
			{
				//把下表为 j 的位置覆盖掉
				int k = 0;
				for (k = j;k < n - 1;k++)
				{
					arr[k] = arr[k + 1];
				}
				n--;//修改去重后元素个数以及坐标的变化
				j--;
			}
		}
	}
	//输出
	for (i = 0;i < n;i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

运行结果:

 5.有序序列的💕合并💕

题目描述:

输入两个升序排列的序列,将两个序列合并为一个有序序列并输出。

输入描述:

输入包含三行,

第一行包含两个整数 n , m (1 <= n , m <=100) , 用空格分隔,n 表示第二行第一个升序序列中数字的个数,m 表示第三行第二个升序序列中数字的个数。

第二行包含 n 个整数(范围1~5000),用空格分隔。

第三行包含 m 个整数(范围1~5000),用空格分隔。

输出描述:

输出为一行,输出长度为 n+m 的升序序列,即长度为 n 的升序和长度为 m 的升序序列中的元素重新进行升序序列排列合并。


题目分析:

1.该题的核心是对两个有序序列的合并,并且合并之后的序列依然是有序序列。我们采用的方法是创建两个变量来表示两个数组的下标,通过循环和两个下标的比较来对前 n 个或者前 m 个元素进行有序打印,之后再打印剩下的元素。

	//有序序列的输出
	i = 0;//用来遍历arr1数组
	int j = 0;//用来遍历arr2数组
	while (i < n && j < m)//对相应序列的前 n 个或者前 m 个进行有序输出
	{
		if (arr1[i] < arr2[j])
		{
			printf("%d ", arr1[i]);
			i++;
		}
		else
		{
			printf("%d ", arr2[j]);
			j++;
		}
	}
	if (i == n)// n 的个数较大,由于开始就是有序序列,直接对之后的序列进行输出
	{
		for (;j < m;j++)
		{
			printf("%d ", arr2[j]);
		}
	}
	else
	{
		for (;i < n;i++)// m 的个数较大,由于开始就是有序序列,直接对之后的序列进行输出
		{
			printf("%d ", arr1[i]);
		}
	}

2.完善整个程序

//有序序列的合并
int main()
{
	int n = 0;
	int m = 0;
	int arr1[100] = { 0 };
	int arr2[100] = { 0 };
	//输入
	printf("请输入两数组的大小 n 和 m:\n");
	scanf("%d %d", &n, &m);
	int i = 0;
	printf("请输入第一个数组元素:\n");
	for (i = 0;i < n;i++)
	{
		scanf("%d", &arr1[i]);
	}
	printf("请输入第二个数组元素:\n");
	for (i = 0;i < m;i++)
	{
		scanf("%d", &arr2[i]);
	}
	//有序序列的输出
	i = 0;//用来遍历arr1数组
	int j = 0;//用来遍历arr2数组
	while (i < n && j < m)//对相应序列的前 n 个或者前 m 个进行有序输出
	{
		if (arr1[i] < arr2[j])
		{
			printf("%d ", arr1[i]);
			i++;
		}
		else
		{
			printf("%d ", arr2[j]);
			j++;
		}
	}
	if (i == n)// n 的个数较大,由于开始就是有序序列,直接对之后的序列进行输出
	{
		for (;j < m;j++)
		{
			printf("%d ", arr2[j]);
		}
	}
	else
	{
		for (;i < n;i++)// m 的个数较大,由于开始就是有序序列,直接对之后的序列进行输出
		{
			printf("%d ", arr1[i]);
		}
	}
	return 0;
}

运行结果:

 在文章的最后,小作者再次送给每位读者一个大大的赞:

 

;