思路:
运用归并排序:
假设给定我们两个都是升序的数组,要求我们要把这两个数组以升序的方式合并到一个数组中,则我们就可以在这两个数组中分别各拿取一个元素进行比较,将二者之间较小值先放在这个新数组中,以此类推。
例子:{3,5}和{4,7}
第一步:3和4先比(因为两个数组都已经是升序了,所以第一个元素一定是该数组最小的元素)
3比4小,则将3放进数组——{3}
第二步:4和5再比,4比5小,则将4放进数组——{3,4}
第三步:5和7再比,5比7小,则将5放进数组——{3,4,5}
第四步:另外一组数组没有元素可以和7比了,那么就将7放进数组——{3,4,5,7}
有了思路我们就要考虑特殊情况了
第一个问题:如果两个数组长度不一样长,等到有一个数组的元素全部用完都放进新数组里面,那接下来该怎么比呢?
其实多想想就有解决办法了——我们可以假设两个数组的长度就是一样长的,只不过我赋值的长度不一样,那么剩下没被赋值的系统就默认为0了,所以我们就变成没被比较完的数组与0比较了;
第二个问题:如果两个数组出现了相同的元素怎么办呢?
其实也不难,那么我们就让它们并列赋值给新数组,只不过最后新数组的下标要一次性加2(因为这次一次性赋值了两个数)
大致有了想法后就可以开始写代码了
答案:
#include <stdio.h>
int main()
{
int n = 0, m = 0, i = 0, j = 0, t = 0;
int arr1[1000] = { 0 }, arr2[1000] = { 0 }, arr3[2000] = { 0 };
scanf("%d%d", &n, &m);
for (i = 0; i < n; i++)
{
scanf("%d", &arr1[i]);
if (arr1[i] < 0 || arr1[i]>30000) //如果输入的值不符合题目要求范围
{
printf("请重新输入规定范围内的数\n");
i--; //重新输入一个值
}
}
for (j = 0; j < m; j++)
{
scanf("%d", &arr2[j]);
if (arr2[j] < 0 || arr2[j]>30000) //如果输入的值不符合题目要求范围
{
printf("请重新输入规定范围内的数\n");
j--; //重新输入一个值
}
}
for (i = 0, j = 0, t = 0; i < n || j < m;) //因为情况很多,所以不适合在for里面改变,于是空过第三部分,跳出循环条件就是当两个数组都用完了(即i==n&&j==m)
{
if (arr1[i] > arr2[j]) //当arr1中大于arr2
{
if (arr1[i] > arr2[j] && j == m) //如果不是数组arr2已经比较完的话
{
arr3[t] = arr1[i]; //将数组arr1传给arr3
i++;
t++;
}
else //如果是arr1和arr2都没用完(即正常情况)
{
arr3[t] = arr2[j];
j++;
t++;
}
}
else if (arr1[i] < arr2[j]) //当arr1中小于arr2
{
if (arr1[i] < arr2[j] && i == n) //如果不是数组arr1已经比较完的话
{
arr3[t] = arr2[j]; //将数组arr2传给arr3
j++;
t++;
}
else //如果是arr1和arr2都没用完(即正常情况)
{
arr3[t] = arr1[i];
i++;
t++;
}
}
else if (arr1[i] == arr2[j]) //当arr1中等于arr2
{
arr3[t] = arr1[i]; //将arr1和arr2并列赋值给arr3
arr3[t + 1] = arr2[j];
i++;
j++;
t = t + 2; //因为这次同时给arr3赋值了2个,所以下标加2
}
}
for (i = 0; i < t; i++) //将合并的arr3打印出来
{
printf("%d ", arr3[i]); //如果要求最后一个值后面不加空格,让下标等于t-1时不加空格即可
}
return 0;
}