计算机等级考试二级C语言程序设计专项训练题——数组元素的移动
在计算机等级考试二级C语言程序设计试题中,按要求对数组元素进行移动处理是一个重要的考点,有关数组元素移动的试题在历年考试试卷的程序填空题和程序设计题中经常出现。
一.例题讲解
例1 编写函数fun,它的功能是:逆置数组元素中的值。
例如,若a所指数组中的数据依次为:1、2、3、4、5、6、7、8、9,则逆置后依次为:9、8、7、6、5、4、3、2、1。
#include <stdio.h>
void fun(int a[], int n)
{
}
int main()
{
int b[9]={1,2,3,4,5,6,7,8,9}, i;
printf("\nThe original data :\n");
for (i=0; i<9; i++)
printf("%4d ", b[i]);
printf("\n");
fun(b, 9);
printf("\nThe data after invert :\n");
for (i=0; i<9; i++)
printf("%4d ", b[i]);
printf("\n");
}
解析1:若数组中有n个元素,则分别将第1个元素(a[0])和第n个元素(a[n-1])对换,第2个元素(a[1])和第n-1个元素(a[n-2])对换,……。因此,逆置操作可写成一个循环,循环次数为数组元素个数的一半。当n为偶数,“一半”恰好是数组长度的二分之一;若n是奇数,“一半”是小于n/2的最大整数,这时取大于n/2的最小整数的位置上的元素,恰是数组中间位置的元素,不需要逆置。描述为:
for (i=0; i<n/2; i++)
{
// 将a[i] 和 a[n-1-i] 互换;
}
编写的函数fun如下:
void fun(int a[], int n)
{
int i,t;
for (i=0; i< n/2; i++)
{
t=a[i];
a[i] = a[n-1- i];
a[n-1-i] = t;
}
}
解析2:数组的逆置还可以采用如下的方法完成。
设置两个变量low和bottom分别指向数组的首尾。逆置操作过程如下:
1)将low指向的内容和bottom指向的内容相交换;
2)修改变量top和bottom,使top后移(top++),bottom前移(bottom--);
3)重复1)、2)操作,直到low>=bottom为止。
编写的函数fun如下:
void fun(int a[], int n)
{
int temp,top,bottom;
top=0;
bottom=n-1;
while(top<bottom)
{
temp=a[top];
a[top]=a[bottom];
a[bottom]=temp;
top++;
bottom--;
}
}
解析3:数组的逆置还可以采用递归的方法完成。
递归终止条件为:当n<2时,数组中的元素不足2个,无需处理直接返回。
递归方式为:当n>=2时,将数组a的n个元素进行逆置可以看成将首尾元素(a[0]和a[n-1])交换后,再将中间的n-2个元素逆置(递归调用fun(a+1,n-2)完成)。
编写的函数fun如下:
void fun(int a[], int n)
{
int t;
if (n<2) return ;
t=a[0]; a[0]=a[n-1]; a[n-1]=t;
fun(a+1,n-2);
}
例2 编写函数fun,它的功能是:计算形参x所指数组中N个数的平均值(规定所有数均为非负数),将所指数组中大于平均值的数据移至数组的前部,小于等于平均值的数据移至数组的后部,平均值作为函数值返回,在主函数中输出平均值和移动后的数据。
例如,有10个非负数:41 17 34 0 19 24 28 8 12 14,平均值为:19.700000
移动后的输出为:41 34 24 28 17 0 19 8 12 14。
#include <stdlib.h>
#include <stdio.h>
#define N 10
double fun(double *x)
{
}
int main()
{
int i;
double x[N];
for(i=0; i<N; i++)
{
x[i]=rand()%50;
printf("%4.0f ",x[i]);
}
printf("\n");
printf("\nThe average is: %f\n",fun(x));
printf("\nThe result :\n",fun(x));
for(i=0; i<N; i++) printf("%5.0f ",x[i]);
printf("\n");
return 0;
}
解析:现求出数组x中N个元素的平均值av,程序描述为
s=0;
for (i=0; i<N; i++) s=s+x[i];
av= s/N;
之后对数组x的各元素x[i]进行扫描,将高于平均分的元素x[i]依次存储到辅助数组y中,其置x[i]=-1(因为规定数组x中所有元素值均为非负数),此时辅助数组中存储了数组x中大于平均值的数据;再对数组x扫描一遍,将元素值不等于-1的元素值(即数组x中不大于平均值的数据)依次增加到辅助数组y中,此时数组y中存储了原数组x中的所有元素,并且大于平均值的数据存储在数组y的前部,小于等于平均值的数据存储在数组y的后部。
最后将数组y的各元素值对应存储(覆盖)到数组x中即可。
编写的函数fun如下:
double fun(double *x)
{
int i, j;
double s, av, y[N];
s=0;
for (i=0; i<N; i++) s=s+x[i];
av= s/N;
for(i=j=0; i<N; i++)
if( x[i]>av )
{
y[j++]=x[i]; x[i]=-1;
}
for(i=0; i<N; i++)
if( x[i]!= -1) y[j++]=x[i];
for(i=0; i<N; i++)x[i] = y[i];
return av;
}
例3 编写函数fun,它的功能是:移动一维数组中的内容,若数组中有n个整数,要求把下标从0到p(含p,p小于等于n-1)的数组元素平移到数组的最后。
例如,一维数组中的原始内容为:1,2,3,4,5,6,7,8,9,10;p的值为3。移动后,一维数组中的内容应为:5,6,7,8,9,10,1,2,3,4。
#include <stdio.h>
#define N 80
void fun(int *w,int p,int n)
{
}
int main()
{
int a[N]={1,2,3,4,5,6,7,8,9,
10,11,12,13,14,15};
int i,p,n=15;
printf("The original data:\n");
for(i=0; i<n; i++) printf("%3d",a[i]);
printf("\n\nEnter p: ");
scanf("%d",&p);
fun(a,p,n);
printf("\nThe data after moving:\n");
for(i=0; i<n; i++) printf("%3d",a[i]);
printf("\n");
return 0;
}
解析:将数组w中的元素w[0]移动到数组的最后,操作描述为
1)暂存w[0]到辅助变量t中;
2)用一重循环将数组元素w[1]~w[n-1]一次前移一位;
3)将暂存的t保存到w[n-1]中。
将上述操作循环执行p+1次,则将下标从0到p(含p,p小于等于n-1)的数组元素平移到数组的最后。
编写的函数fun如下:
void fun(int *w,int p,int n)
{
int i,j,t;
for (i=0;i<=p;i++)
{
t=w[0];
for (j=0;j<n-1;j++)
w[j]=w[j+1];
w[n-1]=t;
}
}
二.程序设计题
1.编写函数fun,其功能是:将形参a所指数组中的前半部分元素中的值和后半部分元素中的值对换。形参n中存放数组中数据的个数,若n为奇数,则中间的元素不动。
例如,若a所指数组中的数据依次为:1 2 3 4 5 6 7 8 9,则调换后为:6 7 8 9 5 1 2 3 4。
#include <stdio.h>
#define N 9
void fun(int a[], int n)
{
}
int main()
{
int b[N]={1,2,3,4,5,6,7,8,9}, i;
printf("\nThe original data :\n");
for (i=0; i<N; i++) printf("%4d ", b[i]);
printf("\n");
fun(b, N);
printf("\nThe data after moving :\n");
for (i=0; i<N; i++) printf("%4d ", b[i]);
printf("\n");
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(int a[], int n) { int i, t, p; p = (n%2==0)?n/2:n/2+1; for (i=0; i<n/2; i++) { t=a[i]; a[i] = a[p+i]; a[p+i] = t; } }
2.编写函数fun,它的功能是:对于给定的下标n,把数组arr中比元素arr[n]小的元素放在它的左边,比它大的元素放在它的右边,排列成的新数组仍然保存在原数组中。
例如,数组arr={33,67,42,58,25,76,85,16,41,65},下标n=3,则移动后数组arr={33,42,25,16,41,58,67,76,85,65}。
#include <stdio.h>
#define N 10
void fun(int arr[], int n)
{
}
int main()
{
int b[N]={33,67,42,58,25,76,85,16,41,65}, i,n;
printf("\nThe original data :\n");
for (i=0; i<N; i++)
printf("%d ", b[i]);
printf("\n");
scanf("%d",&n);
fun(b, n);
printf("\nThe data after moving :\n");
for (i=0; i<N; i++) printf("%d ", b[i]);
printf("\n");
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(int arr[], int n) { int i,j=0,k=0,t; int bb[N]; t=arr[n]; for (i=0;i<N;i++) { if (arr[i]>t) bb[j++]=arr[i]; if (arr[i]<t) arr[k++]=arr[i]; } arr[k++]=t; for (i=0;i<j;i++) arr[k++]=bb[i]; }
3.编写函数fun,它的功能是:计算形参x所指数组中N个数的平均值(规定所有数均为正数),将所指数组中小于平均值的数据移至数组的前部,大于等于平均值的数据移至数组的后部,平均值作为函数值返回,在主函数中输出平均值和移动后的数据。
例如,有10个正数:41 17 34 0 19 24 28 8 12 14,平均值为:19.700000
移动后的输出为:17 0 19 8 12 14 41 34 24 28。
#include <stdio.h>
#include <stdlib.h>
#define N 10
double fun(double *x)
{
}
int main()
{
int i;
double x[N];
for(i=0; i<N; i++)
{
x[i]=rand()%50;
printf("%4.0f ",x[i]);
}
printf("\n");
printf("\nThe average is: %f\n",fun(x));
printf("\nThe result :\n");
for(i=0; i<N; i++) printf("%5.0f ",x[i]);
printf("\n");
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
double fun(double *x) { int i, j; double av, y[N]; av=0; for(i=0; i<N; i++) av +=x[i]; av/=N; for(i=j=0; i<N; i++) if( x[i]<av ) { y[j]=x[i]; x[i]=-1; j++; } i=0; while(i<N) { if (x[i]!=-1) y[j++]=x[i]; i++; } for (i=0; i<N; i++) x[i] = y[i]; return av; }
4.编写函数fun,它的功能是:把形参a所指数组中的最大值放在a[0]中,接着求出a所指数组中的最小值放在a[1]中;再把形参a所指数组中的次大值放在a[2]中,次小值放在a[3]中;其余以此类推。
例如,若a所指数组中数据最初排列为:1、4、2、3、9、6、5、8、7,则按规则移动后,数据排列为:9、1、8、2、7、3、6、4、5。
#include <stdio.h>
#define N 9
void fun(int a[], int n)
{
}
int main()
{
int b[N]={1,4,2,3,9,6,5,8,7}, i;
printf("\nThe original data :\n");
for (i=0; i<N; i++) printf("%4d ", b[i]);
printf("\n");
fun(b, N);
printf("\nThe data after moving :\n");
for (i=0; i<N; i++) printf("%4d ", b[i]);
printf("\n");
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(int a[], int n) { int i, j, max, min, px, pn, t; for (i=0; i<n-1; i+=2) { max = min = a[i]; px = pn = i; for (j=i+1; j<n; j++) { if (max < a[j]) { max = a[j]; px = j; } if (min > a[j]) { min = a[j]; pn = j; } } if (px != i) { t = a[i]; a[i] = max; a[px] = t; if (pn == i) pn= px; } if (pn != i+1) { t = a[i+1]; a[i+1] = min; a[pn] = t; } } }
5.编写函数fun,它的功能是:将N*N矩阵中元素的值按列右移一个位置,右边被移出矩阵的元素绕回左边。
例如,N=4,有下列矩阵
21 12 13 24
25 16 47 38
29 11 32 54
42 21 33 10
移动后结果为
24 21 12 13
38 25 16 47
54 29 11 32
10 42 21 33
#include <stdio.h>
#define N 4
void fun(int (*t)[N])
{
}
int main()
{
int t[][N]={21,12,13,24,25,16,47,38,29,11,32,54,42,21,33,10}, i, j;
printf("The original array:\n");
for(i=0; i<N; i++)
{
for(j=0;j<N;j++) printf("%2d ",t[i][j]);
printf("\n");
}
fun(t);
printf("\nThe result is:\n");
for(i=0; i<N; i++)
{
for(j=0;j<N;j++) printf("%2d ",t[i][j]);
printf("\n");
}
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(int (*t)[N]) { int i, j, x; for(i=0; i< N; i++) { x=t[i][ N-1] ; for(j=N-1; j>0; j--) t[i][j]=t[i][j-1]; t[i][0]=x; } }
6.编写函数fun,它的功能是:将a所指3*5矩阵中第k列的元素左移到第0列,第k列以后的每列元素依次左移,原来左边的各列依次绕到右边。
例如,有下列矩阵
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
若k为2,程序执行结果为
3 4 5 1 2
3 4 5 1 2
3 4 5 1 2
#include <stdio.h>
#define M 3
#define N 5
void fun(int (*a)[N],int k)
{
}
int main( )
{
int x[M][N]={{1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5}},i,j;
printf("The array before moving:\n\n");
for(i=0; i<M; i++)
{
for(j=0; j<N; j++) printf("%3d",x[i][j]);
printf("\n");
}
fun(x,2);
printf("The array after moving:\n\n");
for(i=0; i<M; i++)
{
for(j=0; j<N; j++) printf("%3d",x[i][j]);
printf("\n");
}
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(int (*a)[N],int k) { int i,j,p,temp; for(p=1; p<= k; p++) for(i=0; i<M; i++) { temp=a[i][0]; for(j=0; j< N ; j++) a[i][j]=a[i][j+1]; a[i][N-1]= temp; } }
7.编写函数fun,它的功能是:把字符串中的内容逆置。
例如,字符串中原有的内容为:abcdefg,则调用该函数后,串中的内容为:gfedcba。
#include <string.h>
#include <stdio.h>
#define N 81
void fun(char *s)
{
}
int main()
{
char a[N];
printf("Enter a string: ");gets(a);
printf("The original string is: ");puts(a);
fun(a);
printf("\n");
printf("The string after modified: ");
puts(a);
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(char *s) { int i,j; char t; for (i=0,j=strlen(s)-1;i<j;i++,j--) { t=s[i]; s[i]=s[j]; s[j]=t; } }
8.编写函数fun,其功能是:将形参s所指字符串中的所有字母字符顺序前移,其他字符顺序后移。
例如,s所指字符串为:asd123fgh543df,移动处理后字符串为:asdfghdf123543。
#include <stdio.h>
void fun(char s[])
{
}
int main()
{
char s[80];
printf("Please input: ");
scanf("%s",s);
fun(s);
printf("\nThe result is: %s\n",s);
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(char s[]) { int i, j, k; char p[80], t[80]; j=0; k=0; for (i=0; s[i]!='\0'; i++) { if (((s[i]>='a')&&(s[i]<='z')) ||((s[i]>='A')&&(s[i]<='Z'))) { t[j]=s[i]; j++; } else { p[k]=s[i]; k++; } } for (i=0; i<j; i++) s[i]=t[i]; for (i=0; i<k; i++) s[j+i]=p[i]; }
9.编写函数fun,它的功能是:将s所指字符串中的所有数字字符移到所有非数字字符之后,并保持数字字符串和非数字字符串原有的次序。
例如,s所指的字符串为“def35adh3kjsdtf7”,执行后结果为“defadhkjsdtf3537”。
#include <stdio.h>
void fun(char *s)
{
}
int main()
{
char s[80]="def35adh3kjsdtf7";
printf("The original string is :%s\n",s);
fun(s);
printf("The result string is :%s\n",s);
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(char *s) { int i, j, k; char t1[80], t2[80]; j=0; k=0; for (i=0; s[i]!='\0'; i++) { if (s[i]>='0' && s[i]<='9') { t2[j++]=s[i]; } else { t1[k++]=s[i]; } } for (i=0; i<k; i++) s[i]=t1[i]; for (i=0; i<j; i++) s[k+i]=t2[i]; }
10.编写函数fun,它的功能是:在p所指字符串中找出ASCII码值最大的字符,将其放在第1个位置上,并将该字符前的原字符向后顺序移动。
例如,调用函数前字符串为:GABCDeFGH,调用函数后字符串为:eGABCDFGH。
#include <stdio.h>
void fun(char *p)
{
}
int main()
{
char str[80];
printf("Enter a string:");
gets(str);
printf("\nThe original string: ");
puts(str);
fun(str);
printf("\nThe string after moving: ");
puts(str);
printf("\n\n");
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(char *p) { char max,*q; int i=0; max=p[i]; while (p[i]!=0) { if (max<p[i]) { max=p[i]; q=p+i; } i++; } while (q>p) { *q=*(q-1); q--; } p[0]=max; }
11.编写函数fun,它的功能是:把形参s所指字符串中下标为奇数的字符右移到下一个奇数位置,右边被移出字符串的字符绕回放到第1个奇数位置,下标为偶数的字符不动(注:字符串的长度大于等于2)。
例如,形参s所指字符串为“abcdefgh”,执行结果为“ahcbedgf”。
#include <stdio.h>
void fun(char *s)
{
}
int main()
{
char s[80]="abcdefgh";
printf("The original string is :%s\n",s);
fun(s);
printf("The result string is :%s\n",s);
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(char *s) { int i,k; char c; for (i=0;s[i]!='\0';i++) ; if (i%2==0) k=i-1; else k=i-2; c=s[k]; for (i=k-2;i>=1;i-=2) s[i+2]=s[i]; s[1]=c; }
12.编写函数fun,它的功能是:移动字符串中的内容。移动规则如下:把第1到m个字符平移到字符串的最后,把第m+1到最后的字符移到字符串的前部。
例如,字符串中原有内容为:ABCDEFGHIJK,m的值为3,则移动后,字符串中的内容应该是:DEFGHIJKABC。
#include <stdio.h>
#include <string.h>
#define N 80
void fun(char *w, int m)
{
}
int main()
{
char a[N]= "ABCDEFGHIJK";
int m;
printf("The original string:\n");puts(a);
printf("\n\nEnter m: ");scanf("%d",&m);
fun(a,m);
printf("\nThe string after moving:\n");puts(a);
printf("\n\n");
return 0;
}
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
void fun(char *w, int m) { int k,i,t,n; n=strlen(w); for (k=1;k<=m;k++) { t=w[0]; for (i=1;i<n;i++) { w[i-1]=w[i]; } w[n-1]=t; } }