牛客网刷题小结---C语言---有序序列(详解)
Posted Unstoppedable
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了牛客网刷题小结---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;
}
运行结果:
在文章的最后,小作者再次送给每位读者一个大大的赞:
:
以上是关于牛客网刷题小结---C语言---有序序列(详解)的主要内容,如果未能解决你的问题,请参考以下文章