文章目录
- 解法1:另辟空间法
- 解法2:覆盖法
- 解法3:覆盖法(进阶版)
- 解法4:异或取巧法
题目:有一个整数序列(可能存在重复的整数),编写程序删除序列中指定的某一个整数,输出删除指定数字之后的序列,序列中未被删除数字的前后位置不发生改变。
输入描述
第1行:输入一个整数(0≤N≤50)。
第2行:输入N个整数,输入用空格分隔的N个整数。
第3行:输入想要进行删除的一个整数。
输出描述
输出删除指定数字之后的序列。
解法1:另辟空间法
另外创建一个数组(用来存放删除指定数字之后的序列),来实现输出删除指定数字之后的序列。代码如下:
#include<stdio.h>
void delete_num(int src[], int num, int del)
{
int dest[50] = { 0 };
int i = 0;
int j = 0;
int sz = num;
//删除元素
while (i < num)
{
if (src[i] == del)
{
i++;
sz--;
}
else
dest[j++] = src[i++];
}
//打印数组
for (i = 0; i < sz; i++)
printf("%d ", dest[i]);
}
int main()
{
//输入数组元素个数
int num = 0;
scanf("%d", &num);
//输入数组
int arr[50] = { 0 };
int i = 0;
for (i = 0; i < num; i++)
{
scanf("%d", &arr[i]);
}
//输入需要删除的数
int del = 0;
scanf("%d", &del);
//开始删除,并输出最终数组
delete_num(arr, num, del);
return 0;
}
上面的代码可以达成目的,但这样做的缺点是会另外多开辟一块空间。
解法2:覆盖法
在遍历整个序列时若发现需要删除的元素,则将后面所有的元素向前覆盖一位,这样可以达到最终目的。值得注意,在遍历的时候可能存在重复连续的整数,所以每次找到需要删除的元素后,最好是在删除位置重新往后遍历。如下图所示:
#include<stdio.h>
void delete_num(int arr[], int num, int del)
{
//删除数字
int cur = 0;
while (cur < num)
{
if (arr[cur] != del)
cur++;
else
{
int i = 0;
for (i = cur; i < num - 1; i++)
arr[i] = arr[i + 1];
num--;
}
}
//打印数组
int i = 0;
for (i = 0; i < num; i++)
printf("%d ", arr[i]);
}
int main()
{
//输入数组元素个数
int num = 0;
scanf("%d", &num);
//输入数组
int arr[50] = { 0 };
int i = 0;
for (i = 0; i < num; i++)
{
scanf("%d", &arr[i]);
}
//输入需要删除的数
int del = 0;
scanf("%d", &del);
//开始删除,并输出最终数组
delete_num(arr, num, del);
return 0;
}
上面的代码大大增加了算法的复杂度,原因是使用了两个for循环嵌套。
解法3:覆盖法(进阶版)
解法2中的覆盖法过于繁琐,需要多次重复遍历数组。那么存不存在一种只需要遍历一遍数组解法?答:覆盖法(进阶版)。解题思路:通过两个遍历速度不同的下标交错覆盖,实现删除数字的目的。如下图所示:
#include<stdio.h>
void delete_num(int arr[], int num, int del)
{
int before = 0;
int after = 0;
int sz = num;
//删除数字
while (before < num)
{
if (arr[before] != del)
arr[after++] = arr[before++];
else
{
before++;
sz--;
}
}
//打印数组
int i = 0;
for (i = 0; i < sz; i++)
printf("%d ", arr[i]);
}
int main()
{
//输入数组元素个数
int num = 0;
scanf("%d", &num);
//输入数组
int arr[50] = { 0 };
int i = 0;
for (i = 0; i < num; i++)
{
scanf("%d", &arr[i]);
}
//输入需要删除的数
int del = 0;
scanf("%d", &del);
//开始删除,并输出最终数组
delete_num(arr, num, del);
return 0;
}
解法4:异或取巧法
异或取巧法解题思路:使用'^'
(异或操作符)对序列中所有元素异或上需要被删除的那个数,这样序列中所有需要被删除的数就会变为0。再将那些没有变为0的数异或上需要被删除的那个数,这些数就变回原先的数值。异或的两个特性:
- 相同数值进行异或,结果必为0
- 任意数值与0进行异或,结果必为该数本身
#include<stdio.h>
void delete_num(int arr[], int num, int del)
{
int i = 0;
for (i = 0; i < num; i++)
{
arr[i] ^= del;
}
for (i = 0; i < num; i++)
{
if (arr[i] != 0)
printf("%d ", arr[i] ^ del);
}
}
int main()
{
//输入数组元素个数
int num = 0;
scanf("%d", &num);
//输入数组
int arr[50] = { 0 };
int i = 0;
for (i = 0; i < num; i++)
{
scanf("%d", &arr[i]);
}
//输入需要删除的数
int del = 0;
scanf("%d", &del);
//开始删除,并输出最终数组
delete_num(arr, num, del);
return 0;
}
这份博客👍如果对你有帮助,给博主一个免费的点赞以示鼓励欢迎各位🔎点赞👍评论收藏⭐️,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧👀。