版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
"CaseTutorialsofCLanguageProgramming"isbasedondataprocessing《C语言程序设计案例教程》
----基于数据处理目录02第2章简单的数值运算程序设计03第3章逻辑运算与选择结构程序设计01第1章C语言概述及程序设计基础04第4章重复运算与循环结构程序设计目录06第6章指针与字符串数据处理07第7章函数与程序结构优化05第5章数组与批量数据处理08第8章结构体与复杂数据处理目录10第10章文件与大批量数据处理09第9章链表与非连续存储数据处理第5章数组与批量数据处理01020304055.2一维数组5.1数组和数组元素5.4二维数组5.3运用一维数组进行批量数据处理5.5运用二维数组进行数据运算处理5.1.1数组的引入【例5.1】从键盘输入5个学生的成绩,求这5个学生的平均成绩#include
<stdio.h>
int
main(){
float
a0,a1,a2,a3,a4,aver;
scanf("%f%f%f%f%f",&a0,&a1,&a2,&a3,&a4);
aver=(a0+a1+a2+a3+a4)/5;
printf("平均成绩是:%4.1f\n",aver);}问题分析:1.如何解决更多学生的成绩问题?2.如何存储更多的数据?5.1.1数组的引入【例5.2】从键盘输入n(n代表学生的个数),然后依次输入每个学生的成绩,求这n个学生的平均成绩问题分析:未能解决更多数据的存储。#include<stdio.h>int
main(){ int
i,n;
double
score,sum,average;
do { printf("Pleaseinputstudentsnumbern="); scanf("%d",&n); }while
(n<=0);
//只有输入1个及以上的学生数才有意义,否则重新输入。
sum=0.0;
for
(i=1;i<=n;i++) { printf("The%dstudentscore:",i); scanf("%lf",&score); sum=sum+score; } average=sum/n; printf("%dstudentsaveravgscore=%lf",n,average);}输入正确性的解决方案5.2一维数组类型说明符数组名[常量表达式];(2)将有限个类型相同的变量集中命名,集中存储它们通过一个数组名来统一管理。存储在一块连续的内存空间中(3)数组元素:数组中的每一个变量它们通过数组名[下标]来具体表示,下标从0开始,到数据的最大元素个数-1。(4)数组有一维和多维数组之分一维、二维及多维数组与直线、平面、立体的关系类似5.2.1一维数组的定义和引用
inta[10];
//说明整型数组a,有10个元素。floatb[20];//说明实型数组b,有20个元素。charc[30]; //说明字符数组c,有30个元素。类型说明符数组名[常量表达式];数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。0102035.2.1一维数组的定义和引用5.2一维数组可以是任意数据类型只能是正整型常量标识衔命名要求5.2一维数组2.一维数组的引用数组名[下标]
其中下标是数组元素在数组中的顺序号,可以是常量、整型或表达式,其结果必须是整型。01
下标是有范围
,必须在0~定义时的最大值-1之间,越界出错!02只能逐个引用数组的元素,如a[i]数组名赋予了特定的含义,表示存储数据元素的首地址。035.2一维数组3.一维数组的存储数组名为数组的首地址,如inta[6]
01
数组元素的输入:scanf(“%d”,&a[i]);02地址的用途:可以用地址做等价替换:scanf(“%d”a+i);或赋值:
如:*(a+i)=168;03123456元素地址:aa+1a+2a+3a+4a+5数组首地址a一维数组各元素连续存放。
5.1.2数组的概念#include<stdio.h>int
main(){
int
i,a[5];
//pos表示最大数的位置
printf("输入5个整数(以空格分隔):");
for(i=0;i<5;i++)
//逐个输入数据元素的值
scanf("%d",&a[i]);
//可用scanf("%d",a+i);替代
for
(i=0;i<5;i++)
//逐个输出数据元素的值
printf("%d
",a[i]); printf("\n数组所占存储空间的大小=%d,其首地址为%ld\n",sizeof(a),a);}【例5.3】数组元素的输入与输出首地址值因机器而异
结合数据输入,分析存储特点#include<stdio.h>int
main(){
int
i,a[5];
printf("输入5个整数(以空格分隔):");
for(i=0;i<5;i++)
scanf("%d",&a[i]);
for
(i=0;i<5;i++)
printf("%d
",a[i]); printf("\n数组所占存储空间的大小=%d,其首地址为%ld\n",sizeof(a),a);}【例5.3】数组元素的输入与输出首地址值因机器而异345675456671258105212581056125810601258106412581068地址值内存单元存放的值4字节4字节4字节4字节4字节a[0]a[1]a[2]a[3]a[4]变量空间大小地址表示aa+1a+3a+2a+45.1.2数组的概念连续顺序存放5.2.2一维数组的初始化格式:类型说明符数组名[常量表达式]={值,值,……,值};(1)对所有元素赋初值,例如:inta[5]={5,6,7,8,9};(2)对部分元素赋初值。后面的被自动赋0
inta[5]={2,3,4};(3)对所有元素赋初值时,可以不指定数组长度。例如:inta[]={5,6,7,8,9};(4)初始化只能给数组元素逐个赋值,不能给数组整体赋值。
错误:inta[5]=1;(5)不能对数组名进行赋值。
inta[5];错误:a=100;
5.3运用一维数组进行批量数据处理将一维数组和循环结合起来,可以解决以下常见的问题:(1)数据统计:如计算若干个数据的个数、最大值、最小值、总和、平均值等。(2)数列运算:如Fibonacii数列、约瑟夫问题的求解等。(3)数据增删改运算:如在数组中插入、删除、修改元素的操作。(4)数据排序:按一定的大小顺序将原数组元素排成大小有序有数据,常见的排序算法有冒泡法、选择法等。(5)数据检索:在未排序或已排序的数据序列中查找指定的数据是否存在。5.3运用一维数组进行批量数据处理5.3.1数据统计【例5.4】用数组元素初始化的方法求10个学生的平均成绩,并统计其中不及格学生的个数.#include
<stdio.h>
void
main(){
double
a[10]={78,64,96,53,82,69,72,42,74.5,91.5};
int
i,count=0;
double
sum=0.0,aver;
for
(i=0;i<10;++i)
{
sum+=a[i];
if
(a[i]<60)
count++;
}
aver=sum/10.0;
//计算平均成绩
printf("平均成绩为:%4.2lf,不及格人数为%d个。\n",aver,count);}
本程序算法简单,重点在于掌握
所如获取数组元素。for(i=0;i<10;i++)sum=sum+a[i];5.3运用一维数组进行批量数据处理5.3.1数据统计【例5.5】输入n个整数,找出其最大值与最小值元素的位置,然后将最大值元素与第一个元素交换,将最小值元素与最后一个元素交换
核心问题:(1)求最大值与最小
值(2)交换
为实际指定位置交换数组元素,在求最大值和最小值时需要保留其位置(下标)。void
main(){
int
a[1000];
/在未指定大小时,定义一个元素较多的数组
int
i,n,max,min,pmax,pmin,temp;
scanf("%d",&n);
for
(i=0;i<n;i++)
//输入数组元素的值
scanf("%d",a+i);
max=min=a[0];
//从a[0]开始,
pmax=pmin=0;
for
(i=1;i<n;i++)
{
if
(a[i]>max)
{
max=a[i];pmax=i;
}
//保存新的最大值及其下标
if
(a[i]<min)
{
min=a[i];pmin=i;
}
//保存新的最小值及其下标
}
temp=a[0];a[0]=a[pmax];a[pmax]=temp;
//最大数与a[0]交换
temp=a[n-1];a[n-1]=a[pmin];a[pmin]=temp;//最小数与a[n-1]交换
printf("Afterexchangearrayelementvalue:");
for
(i=0;i<n;i++)
//输出数组元素的值
printf("%d
",a[i]);
printf("\n");}因一屏放不下,省略了部分语句5.3运用一维数组进行批量数据处理5.3.2数列运算【例5.6】输出Fibonacii数列的前20项。a[0]=1;a[1]=1;for(i=2;i<20;i++)a[i]=a[i-1]+a[i-2];核心语句:#include
<stdio.h>
void
main(){
int
i,f[40]={1,1};
for
(i=2;i<40;i++)
f[i]=f[i-1]+f[i-2];
printf("Thebefor40itemvalueofFibonaciiarray:");
for
(i=0;i<40;i++)
{
if
(i%10==0)
printf("\n");//每行显示10个
printf("%8ld",f[i]);
}}5.3运用一维数组进行批量数据处理5.3.2数列运算【例5.7】有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前n项(0<n<40)之和,保留两位小数1.找规律:看分子、再看分母
2.数的存储
利用2个数组,一个存储1,2,3,5,8....
一个存储每一项的值。核心思想:#include<stdio.h>int
main(){ int
n,i;
double
a[100]={1,2,0,0,0},b[100],sum=0;
do { printf("Inputitemnumbers(1-40):"); scanf("%d",&n); }while
(n<=0||n>40); b[0]=a[1]/a[0];
//数列的第一个数
sum=b[0];
//sum等于数列第一个数的值
for
(i=2;i<=n;i++) { a[i]=a[i-1]+a[i-2];
//递推求下一个数字
b[i-1]=a[i]/a[i-1];
//存放数列
sum=sum+b[i-1];
//求和
} printf("sum=%.2f\n",sum);
return
0;}5.3运用一维数组进行批量数据处理5.3.2数列运算【例5.8】约瑟夫问题。现在有
n
个人,每个人都有属于自己的编号,分别是
1~
n。所有人呈圆环状排列,每隔
m个人就淘汰一个人
,最后只能有一个人留下来,求这个人的编号核心思想:1234567891012045078010123000450080101234560004000000123459876原始状态第1圈淘汰第2圈淘汰第3圈淘汰约瑟夫问题:n=10,m=35.3批量数据处理#include
<stdio.h>
int
main(){
int
a[100],b[100];
int
n,m,i;
//n总人数,m淘汰数
int
p,k,count;
//p当前数组元素位置,k存入b数组位置,count计数器
do
{
printf("InputtotalPeoples--n(n<100)
&expelnumber--m:");
scanf("%d%d",&n,&m);
}while
(n<=0||n>100||m<=0);
for
(i=0;i<n;i++)
a[i]=i+1;
//以编号1-n初始化数组
k=0;p=0;count=0;
//赋初值
do
{
if
(a[p]!=0)
//未淘汰的人进行报数
{
count++;
//计数器+1
if
(count==m)
//计数到指定淘汰的数
{
b[k++]=a[p];
//淘汰的编号保存到b数组中
a[p]=0;
//淘汰的编号置0
count=0;
//启动下一次报数
}
}
p=(p+1)%n;
//下一个元素下标的处理
}while
(k<n);
//只要还有人要被淘汰,则循环继续
printf("Inturnexpelpeoplenumberis:");//依次输出被光源人的编号
for
(i=0;i<n;i++)
printf("%5d",b[i]);
printf("\nThelaststaypeopleis%d\n",b[n-1]);//留下的人}5.3运用一维数组进行批量数据处理5.3.3数组排序【例5.9】用选择法对输入的10整数按从小到大排序选择法核心思想:(1)每次在未排序的序列中找出其最大元素(或最小元素)与其第一个元素(指未排序序列中的第一个)进行交换,(2)依次重复进行(1),直到执行n-1交换后(3)数据变成了有序序列。5.3.3数组排序选择法排序过程:24457892128798123666123457892128798246661239878921287452466612398927812874524666123989287127845246661239892877812452466612398928778664524612123989287786645246121239892877866452461212398928778664524126原始数据第1次交换后第2次交换后第3次交换后第4次交换后第5次交换后第6次交换后第7次交换后第8次交换后第9次交换后posposposposposposposposposi=0i=1i=2i=3i=4i=5i=6i=7i=85.3.3数组排序选择法程序:#include
<stdio.h>
void
main(){
int
i,j,pos,t,a[10];
printf("Input10numbers:");
for
(i=0;i<10;i++)
scanf("%d",&a[i]);
for
(i=0;i<10;i++)
//第i轮排序
{
pos=i;
for
(j=i+1;j<10;j++)
//找最大元素
if
(a[j]>a[pos])
pos=j;
if
(i!=pos)
{
t=a[i];a[i]=a[pos];a[pos]=t;//最大元素与未排序有第一个元素交换
}
printf("The%d'sswap:",i+1);
//输出每趟交换后的结果(如不用可以省略4行)
for
(j=0;j<10;j++)
printf("%8d",a[j]);
printf("\n");
}
printf("Aftersorted:");
for
(i=0;i<10;i++)
printf("%8d",a[i]);
printf("\n");}(1)(2)(3)(4)(5)(6)分析每部分代码的作用5.3运用一维数组进行批量数据处理5.3.3数组排序【例5.10】用交换法对输入的10整数按从小到大排序交换法核心思想:(1)两两相邻元素比较,如不满足排序规律则进行交换(2)这样进行一趟排序后得到的结果是第一个或最后1个元素是最大的或者是最小的(3)重复上述过程,直到所有数据有序。根据其比较的顺序(下标从小到大、或下标从大到小)与交换规律,交换排序又称为冒泡排序。交换法排序过程:5.3.3数组排序交换法程序:#include
<stdio.h>
void
main(){
int
i,j,pos,t,a[10];
printf("Input10numbers:");
for
(i=0;i<10;i++)
scanf("%d",&a[i]);
for
(i=0;i<10;i++)
//第i轮排序
{
for
(j=0;j<=10-2-i;j++)
//相邻元素比较交换
if
(a[j]>a[j+1])
{
t=a[j];a[j]=a[j+1];a[j+1]=t;
}
printf("The%d'sswap:",i+1);
//输出每趟交换后的结果(可以省略以下3行)
for
(j=0;j<10;j++)
printf("%8d",a[j]);
printf("\n");
}
printf("Aftersorted:");
for
(i=0;i<10;i++)
printf("%8d",a[i]);
printf("\n");}(1)(2)(3)(4)(5)分析每部分代码的作用5.3运用一维数组进行批量数据处理5.3.4数组查找插入删除修改操作1.查找、插入、删除、修改操作的意义查找运算通常又是显示信息、修改数据、插入数据或删除数据的基础,即查到以后很可能要执行:(1)浏览操作:这时必须显示出与其相关的信息内容,例如根据车牌查找车辆信息、根据身份证号码查找人的信息等;(2)修改操作:即在显示原信息的基础上修改相关信息,如公安户籍信息中的更改姓名、更改年龄等各种操作、教务系统中更改学生学籍信息等等;(3)删除操作:删除查到的相关信息,删除操作是保证数据的一致性的重要内容之一,即对录入可能重复或者一些已经失效的信息经常需要定期执行删除操作。(4)插入操作:如数据未找到,需要插入一条新的记录。5.3运用一维数组进行批量数据处理2.查找运算【例5.11】在具有n个(1≤n<≤100)无序整数中查找指定的数,如果找到了,输出其下标位置,否则输出“Notfoundthisdata**”,要求能够重复查询,是否查询根据提示信息输入字符’y’则继续,否则终止查询。核心思想:(1)设数组为a[100],待查找的数据为x,(2)查找过程为从a[0]开始依次将a[i]与x比较,如果相等则找到,输出其下标i(如有相同情况均可以找到),否则继续。(3)如果找遍了整个数组仍未找到,则printf("Notfoundthisdata%d",x);5.3.4数组查找插入删除修改操作查找程序:#include
<stdio.h>
int
main(){
int
a[100];
int
i,n,x,found;
//x待查找的数据,found是否查到的标记(0未查到,1查到)
char
ch;
do
{
printf("Inputtotalnumbers--n(n<100):");
scanf("%d",&n);
}while
(n<=0||n>100);
for
(i=0;i<n;i++)
scanf("%d",a+i);
do
{
printf("Inputyouwantsearcheddata:");
scanf("%d",&x);
found=0;
for
(i=0;i<n;i++)
{
if
(a[i]==x)
//比较
{
printf("found:subscriptis:%d",i);found=1;
}
}
if
(found==0)
printf("Notfoundthisdata%d",x);
printf("\nContinue?(Y--yes,N-no):");
while
((getchar())!='\n');
//读取缓冲区字符直到结束并丢弃他们。
}while
(getchar()=='y'
||getchar()=='Y');}(1)(2)(3)(4)5.3运用一维数组进行批量数据处理【例5.12】在具有n个(1≤n≤100)已按整数由小到大排列的有序数据中查找指定的数,如果找到了,输出其下标位置,否则输出“Notfoundthisdata**”二分查找核心思想:(1)给定查找区间的起点(设为low)和终点(设为high)下标(2)找其中点位置(设为mid,且mid=(low+high)/2)(3)如果a[mid]==x;则查找成功,终止查找;(4)如果a[mid]>x,则修改high=mid-1(缩小查找区间);如果a[mid]<x,则修改low=low+1(缩小查找区间);(5)重复上述过程,如果没有查到,则一定会出现low>high的情况。2.查找运算二分查找过程:1512347892165248321356756123323452736a[0]a[13]lowhighmid有序数待查数x=12331512347892165248321356756123323452736a[0]a[13]lowhighmid1512347892165248321356756123323452736a[0]a[13]lowhighmid1512347892165248321356756123323452736a[0]a[13]lowmidhighmid=(low+high)/2a[mid]<xlow=mid+1a[mid]<xlow=mid+1a[mid]>xhigh=mid-1a[mid]==xfounda[6]a[10]a[12]a[11]二分查找程序:#include
<stdio.h>
int
main(){
int
a[14]={1,5,12,34,78,92,165,248,321,356,756,1233,2345,2736};
int
low,high,mid,x;
//x待查找的数据
low=0;high=13;
printf("Inputyouwantsearcheddata:");
scanf("%d",&x);
while
(low<=high)
{
mid=(low+high)/2;
printf("--%d%d",mid,a[mid]);
//此语句可用于查看查找的比较过程
if
(a[mid]==x)
break;
//查到,直接终止循环
else
if
(a[mid]>x)
high=mid-1;
//中值大于待查数,调整区间上限
else
low=mid+1;
//中值小于待查数,调整区间下限
}
if
(low<=high)
printf("Found:subscriptis:%d\n",mid);
//查到
else
printf("Notfoundthisdata%d\n",x);
//没有查到}(1)(2)(3)5.3运用一维数组进行批量数据处理【例5.13】在一个数组的指定位置插入一个数据:如inta[100],插入前实际有效数据为n(n<100),现指定在第k个数据位置(数据的位置从1开始依次计数)插入1个数据x。核心思想:3.插入运算指定位置插入特定位置插入(如排序)(1)找位置(指定位置可跳过此步)(2)移动数据,为待插入的数据腾出一个空间(请注意移动方向)(3)插入数据数据插入过程:在第7个数的位置插入数据100,意味着要将第7个数以后(含)的所有数据均后移一个位置,此时注意移动方向。#include
<stdio.h>
int
main(){
int
a[100];
int
n,x,k,i,j;
do
{
printf("Inputdatanumbers:");
scanf("%d",&n);
}while
(n<=1||n>99);
//判定n的合法性
for
(i=0;i<n;i++)
scanf("%d",a+i);
do
{
printf("Inputyouwantinsertedpositionandnew-data:");
scanf("%d%d",&k,&x);
}while
(k<1||k>n+1);
//判定位置k的合法性
j=n-1;
//i指向实际数据的最后一个数
while
(j>=k-1)
{
a[j+1]=a[j];
//向后移动数据
j--;
}
a[k-1]=x;
//插入
printf("Afterinsertedarraydata:\n");
for
(i=0;i<n+1;i++)
printf("%5d",a[i]);
printf("\n");}插入程序:(1)(2)(4)(3)5.3运用一维数组进行批量数据处理【例5.14】在一组已经排序的数据中插入一个新的数,使得插入后数组元素依然保持有序。核心思想:3.插入运算指定位置插入特定位置插入(如排序)(1)找位置(2)虑到需要为待插入的数据腾出空间,找位置从后面往前面找,将找位置与数据移动结合起来(边找边移动),这样效率会更高。(3)插入数据数据插入过程:假设插入数据100后,仍保持数列有序,则从未部开始比较与移动
1
5
12
34
78
92
165
248
321
356
756
1233
2345
2736i=0i=13待插入X=100a[i]>x则向后移动ai+1]=a[i];i--;
1
5
12
34
78
92
165
248
321
356
756
1233
2345
2736
2736
i=i-115
12
34
78
92
165
165
248
321
356
756
1233
2345
2736K=1a[i]<100i的移动方向插入a[i+1]=x;15
12
34
78
92100165
248
321
356
756
1233
2345
2736a[i+1]=100找到插入位置插入程序:#include
<stdio.h>
int
main(){
int
a[15]={1,5,12,34,78,92,165,248,321,356,756,1233,2345,2736};//数组定义了15个元素,但初始数据为14个
int
x,i;
printf("Inputyouwantinserteddata:");
scanf("%d",&x);
i=13;
//初始数据为14个,其最后一个数据的下标为13
while
(a[i]>x&&i>=0)
{
a[i+1]=a[i];
//向后移动数据
i--;
}
a[i+1]=x;
//插入
printf("Afterinsertedarraydata:\n");
for
(i=0;i<15;i++)
printf("%5d",a[i]);
printf("\n");}(1)(2)(3)5.3运用一维数组进行批量数据处理【例5.15】在一个数组的指定位置删除一个数据:如inta[100],删除前实际有效数据为n(n≤100),现指定在第k个数据位置(数据的位置从1开始依次计数)删除1个数据,要求编写相应的程序核心思想:4.删除运算指定位置删除特定值后再删除(1)找位置(指定位置可跳过)(2)删除一个数意味着其后面的数均要向前移动1个位置,这种移动方向与插入相反(3)数组的总数-1数据删除过程:删除第7个数65的过程178551273417892652483721356756332345236K=1K=7待删除位置kj=k-1向前移动a[j]=a[j+1];j++1785512734178922482483721356756332345236K=1K=7,j=k-11785512734178922483721356756332345236236K=1K=7j的移动方向j=n-2
注意:最后1个数236仍然存在,但通过改变数组元素的个数可以使它成为不能访问的数。删除程序:#include
<stdio.h>
int
main(){
int
a[100];
int
n,x,k,i,j;
do
{
printf("Inputdatanumbers:");
scanf("%d",&n);
}while
(n<=1||n>100);
//判定n的合法性
for
(i=0;i<n;i++)
scanf("%d",a+i);
do
{
printf("Inputyouwantdeletedposition:");
scanf("%d",&k);
}while
(k<1||k>n);
//判定位置k的合法性
j=k-1;
//i指向第k个位置,其下标为k-1
while
(j<n-1)
{
a[j]=a[j+1];
//向前移动数据
j++;
}
printf("Afterdeletedarraydata:\n");
for
(i=0;i<n-1;i++)
printf("%5d",a[i]);
printf("\n");}(2)(3)(1)(3)5.3运用一维数组进行批量数据处理【例5.16】在一个数组中删除指定的数据,如果指定的数据不存在,则不做删除;如果存在的数据有多个,则全部将其删除。要求编写相应的程序。核心思想:4.删除运算指定位置删除特定值后再删除(1)方法一简单,下面只讨论方法二(一遍循环完成重数据的删除)(2)出现要删除的数时,先统计其出现的次数,直到下一个数不是要删除的数时,此时进行移动,其移动方式为:a[k-count]=a[k].(3)直到数组的最后1个数。指定位置删除特定值后再删除一遍循环删除1个数,再重复一遍循环完成删除数据删除过程:22234535562234562删除2i=p=k=034532234535562234562ki,p3453556234535562234562ki,p345355634534535562234562ki,p345355634565562234562ki,pcount=3count=5count=6删除重复元素程序:int
main(){
int
a[100];
int
n,x,i,k,
count;
printf("Inputdatanumbers:");
scanf("%d",&n);
for
(i=0;i<n;i++)
scanf("%d",a+i);
printf("Inputyouwantdeleteddata:");
scanf("%d",&x);
count=0;
k=0;
for
(i=0;i<n;i++)
{
while
(a[i]==x&&i<n)
{
count++;
//count累计与x相等的数的个数
i++;
//移到下一个比较的元素
}
if
(count>0)
{
a[k]=a[k+count];
//将不等于x的数进行数据移动(跳过删除的count个x跨度)
k++;
//下一个移动数据的起点自动+1
}
else
k=i+1;
//count=0表示到当前下标i为止没有等于x的数,下一移动到的位置k为i+1位置
}
printf("Afterdeletedarraydata:\n");
for
(i=0;i<n-count;i++)
printf("%5d",a[i]);
printf("\n");}(2)(3)(1)(4)5.3运用一维数组进行批量数据处理【例5.17】输入正整数a和b,其中a和b都小于32767,求a/b的值,要求精确到小数点后n位,其中1<n<200核心思想:5.3.5高精度运算指定位置删除特定值后再删除(1)将分数的结果分为整数与小数两部分,分别存储(2)由于小数的位数不确定(最高可达200位),因此用数组进行存储,每个元素瞧位小数(3)按列除式的方式模拟人工运算,直到达到指定的位数止突破常规类型的取值范畴得到高精度的数据结果除法运算过程:17131.3071339401010009730第一个余数r第二个余数r第三个余数r第n位小数=除数b被除数a第n个余数*10除数b第n个余数=(第n-1个余数*10)%除数步骤:商s:s=a/b;余数r:r=a%b;新的被除数:a=r*10重复以上过程即可。#include
<stdio.h>intmain()
{
int
i,a,b,n,s;
int
result[200]={0};
do { printf("输入分子a分母b小数位数(空格分隔):"); scanf("%d%d%d",&a,&b,&n); }while
(n<0||n>200); s=a/b;
//商的整数部分
a=a%b;
//余数,用于求其纯小数商
for
(i=0;i<n;i++) { a=a*10;
//余数*10 result[i]=(a/b);
//保存1位商
a=a%b;
//新的余数
} printf("%d.",s);
//输出商的整数部分
for
(i=0;i<n;i++)
//输出商的整数部分
printf("%d",result[i]); printf("\n");
return
0;}高精度分数的程序:(2)(3)(1)(4)5.3运用一维数组进行批量数据处理【例5.18】编程求n!(0≤n≤100)核心思想:5.3.5高精度运算指定位置删除特定值后再删除(1)因100!有158位,所以必须解决结果的存储问题,用数组,每个数组元素存储1位数据。(2)假设已求出k!,然后用上述结果再乘以k+1后,做数据处理,使得每个数据元素只保留1位数值。(3)用模拟人工乘法的方式来做,从最低位开始乘以K+1。突破常规类型的取值范畴得到高精度的数据结果#include
<stdio.h>#define
N
200//定义数组长度int
main(){
int
a[N],i,j,k,n;
//k运算结果的总位数
do
{
printf("请输入一个整数:");
scanf("%d",&n);
}while
(n<0||n>100);
for
(i=0;i<N;i++)//初始化数组
a[i]=0;
a[0]=1;//相当于乘积变量的初始值为1
k=1;
//初始1表示是1位数
for
(i=1;i<=n;i++)
//计算阶乘
{
for
(j=0;j<k;j++)
a[j]=a[j]*i;
//每一位与i相乘
for
(j=0;j<k;j++)
{
if
(a[j]>9)
//判断是否需要进位
{
a[j+1]=a[j+1]+a[j]/10;//高一位加上低位的进位值
a[j]=a[j]%10;
//当前位保留个位数
if
(j==k-1)k++;
//已到了最后1个数组元素但它仍然是1个2位数以上的数,则需要增加数据的总位数,直到每个数组元素均只存储1位数据
}
}
}
printf("总位数=%d\n
%d!=",k,n);
for
(i=k-1;i>=0;i--)//倒序输出结果
printf("%d",a[i]);
printf("\n");}求n!的程序:(2)(3)(1)(4)5.4二维数组认识二维数组:5.4.1二维数组的定义与引用设有一个N行M列的矩阵,记为ANM,(N、M为正整数)(1)水平方向称为行,从第0行开始,到N-1止。(2)垂直方向称为列,从第0列开始,到M-1止。(3)第i行和第j列交叉处的元素称为a[i][j],0≤i<N,0≤j<M1.二维数组的定义123467891112131415161718行列数学上称为矩阵,计算机中称为二维数组:5.4二维数组二维数组的定义明确了:5.4.1二维数组的定义与引用(1)矩阵的行数与列数,记为ANM,(N、M为常量,且必须是正整数)(2)设i为行,则i的变化范围从第0行开始,到N-1止。(3)设j为列,则j的变化范围从第0列开始,到M-1止。(4)元素引用:第i行和第j列交叉处的元素称为a[i][j],0≤i<N,0≤j<M(5)所有数据元素的类型均相同(6)多维拓展:如inta[2][3][4],b[3][4][5][2];1.二维数组的定义与引用123467891112131415161718第1行第1列二维数组定义的一般形式是:
类型说明符
数组名[N][M]如:inta[4][4];第0行第0列a[2][1]的值为125.4二维数组关于存储需要掌握的:1.行主序存放;连续存放2.可以看成多个一维数组,如a[1]3.重点讲清楚右图中各地址的概念与表示方式。4.每个数组元素占有相同的存储空间5.4.1二维数组的定义与引用3.二维数组在内存中的存储1234678911121314行列inta[3][4];5.4二维数组二维数组与地址有关的概念(1)二维数组名a:二维数组的首地址,也是第一行的行首地址,a+1为第二行的行首地址,……,a+i为第i+1行的行首地址。(2)a[i]:将二维数组的每一行视为一个一维数组,则这个一维数组就是a[i],所以a[i]又称为一维数组的首地址,a[i]+j就是对应元素a[i][j]的地址。(3)行首地址可以通过*运算转化为对应的一维数组的首地址,即*(a+i)与a[i]的作用是等价的。(4)二维数组据点的存储空间的总字节数=行*列*sizeof(元素类型)。【例5.19】二维数组的输入与输出示例int
main(){
int
a[3][4],i,j;
printf("输入二维数组a[3][4]的12个整数:");
for
(i=0;i<3;i++)
for(j=0;j<4;j++)
scanf("%d",&a[i][j]);
//可替换为scanf("%d",a[i]+j);或scanf("%d",*(a+i)+j);
for
(i=0;i<3;i++)
{
for
(j=0;j<4;j++)
printf("%4d",a[i][j]);
printf("\n");
}
printf("数组a所占存储空间大小=%d\n",sizeof(a));
printf("首地址%p,第2行的首地址=%p,第3行的首地址=%p\n",a,a+1,a+2);
printf("第1个一维数组的首地址%p,第2个一维数组的首地址=%p,第3个一维数组的首地址=%p\n",a[0],a[1],a[2]);}通过结果理解二维数组的存储规律与地址的概念。5.4二维数组5.4.2二维数组的初始化二维数组可按行分行赋值(每行均用{}分隔),也可按行连续赋值。(1)对所有元素赋初值。例如:inta[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};//按行赋值每行加{}或者:inta[4][3]={1,2,3,4,5,6,7,8,9,10,11,12};(2)对部分元素赋初值。未赋值的自动赋0inta[4][3]={{1},{2},{3},{4,2}};inta[3][3]={{1},{2,3},{4,5,6}};//对下三角形部分元素赋值inta[4][3]={1,2,3,4,5,6,7,8
};//对前2行赋值,第3行为0(3)对所有行均有元素赋初值时,可省略第一维的长度,但是不能省略第二维的长度。例如:inta[][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}};inta[][3]={{1,2,3},{4},{7,8}};对以上每种赋值画出矩阵的数据5.5运用二维数组进行数据运算处理(3)特殊矩阵010203(2)矩阵运算如计算m×n矩阵中的每行、每列、对角线上元素的和、平均值、最大值、最小值。如矩阵相加或相减、转置、乘法。如杨辉三角形、N阶魔方阵等。(1)矩阵中数的统计5.5运用二维数组进行数据运算处理【例5.20】编写程序,在如下二维数组a[3][4]中选出各行最大的元素组成一个一维数组b[3]核心思想:
在数组a的每一行(如第i行)中寻找最大的元素,找到之后把该值赋予数组b[i]元素即可8112350934115821617863292#include
<stdio.h>int
main(){
int
a[][4]={81,123,50,93,41,15,82,16,17,86,32,92};
int
b[3],i,j,max;
for
(i=0;i<=2;i++)
{
max=a[i][0];
for
(j=1;j<=3;j++)
//求第i行的最大值
if
(a[i][j]>max)max=a[i][j];
b[i]=max;
//最大值保存到b数组中
}
printf("数组b:\n");
for
(i=0;i<=2;i++)
printf("%5d",b[i]);
printf("\n");}5.5.1
矩阵中数的统计5.5运用二维数组进行数据运算处理【例5.21】编程对表5.1最后一行统计课程平均分,最后一列统计学生总分核心思想:
对二维数组的每行与每列进行统计即可。姓名语文数学英语物理化学总分张三8087458576
李四7565635277
王五9288707865
平均分
#include
<stdio.h>void
main(){
float
a[4][6]={{80,87,45,85,76},{75,65,63,52,77},{92,88,70,78,65}};
int
i,j;
for
(i=0;i<=2;i++)
for
(j=0;j<=4;j++)
{
a[i][5]+=a[i][j];
//行元素累加存入最后一列
a[3][j]+=a[i][j];
//列元素累加到最后一行
}
for
(j=0;j<=5;++)
//最后一行求平均值
a[3][j]=a[3][j]j/3.0;
printf("数组a:\n");
for
(i=0;i<4;i++)
{
for
(j=0;j<6;j++)
printf("%8.2f",a[i][j]);
printf("\n");
}}5.5.1
矩阵中数的统计5.5运用二维数组进行数据运算处理【例5.22】二维数组中的鞍点是指该位置上的元素在该行上是最大的数、并且在该列上是最小的数。根据上述定义,一对于个m×n的整数矩阵,有可能有多个鞍点,也可能没有鞍点。编程求出所有的鞍点并以(行,列)=值的形式输出,如果没有鞍点,则输出“NONE”算法分析:(1)设置1个一维数组rowmax,存放每行的最大元素值;(2)设置1个一维数组colmin,存放每列的最小元素值;(3)对数组中的任何一个元素matrix[i][j]如果满足条件:matrix[i][j]==rowmax[i]&&matrix[i][j]==colmin[j]则是鞍点;(4)设置1个found变量,用于记录数组中是否有鞍点,如果没有则输出“NONE”。5.5.1
矩阵中数的统计鞍点程序:int
main(void){
int
matrix[6][6];
int
rowmax[6],colmin[6];
int
i,j,m,n,found;
found=0;
//found鞍点标记,0--没有
1--有
printf("Inputrow&colnumber=");
scanf("%d%d",&m,&n);
printf("Inputmatrixelementdata\n");
for
(i=0;i<m;i++)
for
(j=0;j<n;j++)
scanf("%d",&matrix[i][j]);
printf("Matrixelementis:\n");
for
(i=0;i<m;i++)
{
for
(j=0;j<n;j++)
printf("%6d",matrix[i][j]);
printf("\n");
}
for
(i=0;i<m;i++)
//求每行的最大数,保存到rowmax数组中
{
rowmax[i]=matrix[i][0];
for
(j=1;j<n;j++)
if
(rowmax[i]<matrix[i][j])
<
rowmax[i]=matrix[i][j];
}
for
(j=0;jn;j++)
//求每列的最小数,保存到colmin数组中
{
colmin[j]=matrix[0][j];
for
(i=1;i<m;i++)
if
(colmin[j]>matrix[i][j])
colmin[j]=matrix[i][j];
}
printf("Possibleandianis:\n");
for
(i=0;i<m;i++)
{
for
(j=0;j<n;j++)
if
(matrix[i][j]==rowmax[i]&&matrix[i][j]==colmin[j])
{
printf("(%d,%d)=%d\n",i,j,matrix[i][j]);
found=1;
//有鞍点,found=1,否则found=0
}
}
if
(found==0)
//没有找到鞍点
printf("
NONE\n");
return
0;}5.5运用二维数组进行数据运算处理【例5.23】求矩阵的转置核心思想:
设原矩阵为a[m][n],考虑到原矩阵的行与列值可能不相等,则必须使用1个新矩阵来保存转置后的结果。
设矩阵转置后的为b[n
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 动物检疫检验工考试试题及参考答案
- 2026年互联网保险行业市场现状与未来五年发展趋势报告
- 2026年涂料助剂行业技术创新动态报告
- 2026年膨胀剂行业创新分析报告
- 2026国家开放大学电大专科《民法学(1)》期末试题及答案
- 2026年北师大版数学六年级下册第一单元知识梳理模拟试卷及答案
- 2026广东申论试题及答案
- 人教PEP六年级英语上册Unit1至Unit3语法易错纠错卷(含答案)
- 2026年中国长江动力集团有限公司人员招聘笔试参考题库及详细答案解析
- 2026医养结合服务模式创新与可持续发展研究报告
- 2025浙江鹿城农商银行春季招聘笔试历年典型考题及考点剖析附带答案详解
- 2026年熔化焊接与热切割作业考试题库及模拟考试附答案
- 2026国家电投集团所属国家核电招聘(41人)笔试历年典型考点题库附带答案详解
- 2025年高考全国卷理科综合真题完整版(含标准答案+详细解析)
- 留置看护辅警考试面试真题(附答案)
- 服装企业面料采购质量控制方案
- 智慧城市重大危险源在线监控及事故预警平台规划方案
- 单县羊肉汤介绍
- 医务人员院感考试试题及答案
- 2025四川绵阳市绵投置地有限公司人力资源岗等岗位拟录用人选笔试历年参考题库附带答案详解
- TCTSS 3-2024 茶艺职业技能竞赛技术规程
评论
0/150
提交评论