【项目2 - 删除数组元素】
del函数的作用是删除数组a中的指定元素x,n为数组a的元素个数。函数的返回值,为删除元素后的有效元素个数(数组中可能有重复元素)。函数的原型为:
int del (int a[10],int n,int x)
(1)请实现这个函数,并完成测试。
[参考解答]
#include<stdio.h> int del(int a[],int n, int x); int main( ) { int a[20]= {86,76,62,58,77,85,92,80,96,88,77,67,80,68,78,87,64,59,61,76}; int i, n; n = del(a, 20, 77); printf("剩余 %d 个:\n", n); for(i=0; i<n; i++) printf("%d ", a[i]); printf("\n"); return 0; } int del(int a[],int n, int x) //删除长度为n的a数组中值为x的元素 { int p=0, q=0; //用p和q两个变量 while (q<n) //由q控制,扫描所有的元素 { if(a[q]!=x) //只有当元素值不等于x才往p标识的位置上“搬” { a[p]=a[q]; p++; } q++; } //最后的效果,等于x的元素都没有“搬”过来,它们被“覆盖”了,也即被删除了 return p; //p代表的,就是删除后的元素个数 }
(2)如果在函数调用时,要求数组中的元素呈升序排列呢?
[参考解答]
思路:例如在下面main函数中的测试,删除77时,分三个阶段:①先找到77;②跨过若干个77后,找到了80;③从80开始,将数据逐个地搬到前面合适的位置(“覆盖”了77及随后的位置)。#include<stdio.h> int del(int a[],int n, int x); int main( ) { int a[20]= {58, 59, 61, 62, 64, 67, 68, 76, 77, 77, 77, 80, 80, 85, 86, 87, 88, 88, 92, 96}; int i, n; n = del(a, 20, 77); printf("剩余 %d 个:\n", n); for(i=0; i<n; i++) printf("%d ", a[i]); printf("\n"); return 0; } int del(int a[],int n, int x) //删除长度为n的a数组中值为x的元素 { int p=0, q; while (a[p]<x && p<n) //阶段①:先隔过所有小于x的元素,找到要删除元素的位置 p++; q=p; //阶段②:p将标记住这个待删除的位置 while(a[q]==x && q<n) //q接棒往前走,找到要保留的元素 q++; while(q<n) a[p++]=a[q++]; //阶段③:将要保留的元素,直接“覆盖”到p标记住的位置,逐个赋值,结果就是将等于x的元素删除了 return p; //p代表的,就是删除后的元素个数 }
后记:实际上,对于本项目中涉及问题,利用好这个有序的特征,反倒使处理变得复杂了,同时也没有带来效率上的提高——和对于无序数组一样,都要“扫描”整个数组。但是,这样的问题如果在工程中,尤其是当n很大时,阶段①的工作可以用二分法完成,这是改进思路之一。另外,存储结构不一定用数组这种顺序存储的结构。总之,这一段程序,作为学习过程中“活动”脑瓜的一个游戏,玩玩也挺好。