版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第6章数组与字符串第6章数组与字符串6.1数组与字符串的引入6.2一维数组6.3二维数组6.4字符串及其处理6.5数组与字符串程序设计及实例中国6.1数组与字符串的引入【引例】输入100名学生的姓名和某门课程的成绩,要求把高于平均分的那些学生打印出来,并按照成绩从高到低进行排序输出。6.1.1问题与引例前几章使用的变量都属于基本类型,例如整型、字符型、浮点型数据,这些都是简单的数据类型。对于有些数据,只用简单的数据类型是不够的,难以反映出数据的特点,也难以有效地进行处理。6.1数组与字符串的引入三个数按从小到大排序代码如下:#include<stdio.h>voidmain(){inta,b,c,t;printf("输入三个数:");scanf(“%d,%d,%d”,&a,&b,&c);//输入三个数据
if(a>b){t=a;a=b;b=t;}//交换a、bif(a>c){t=a;a=c;c=t;}//交换a、c
if(b>c){t=b;b=c;c=t;}//交换b、cprintf("三个数从小到大排列为:%d,%d,%d\n",a,b,c);}思考:100个数呢?应该定义多少个变量?如果有1000名学生,每个学生有一个成绩,需要求这1000名学生的平均成绩。用s1,s2,s3,……,s1000表示每个学生的成绩,能体现内在联系。C语言用方括号中的数字表示下标,如用s[15]表示数组s中有15个元素。6.1数组与字符串的引入把具有相同类型的若干个数据按有序的形式组织起来,这些按序排列的相同类型数据的集合称为数组,一个数组必须用一个数组名表示。数组中的每一个数据称为数组元素,数组元素用数组名加下标表示,下标表示数组元素在数组中的位置。数组元素用一个下标表示的称为一维数组,数组元素用两个下标表示的称为二维数组,数组元素用两个以上下标表示的称为多维数组。6.1.2数组的基本概念数组是一组有序数据的集合。数组中各数据的排列是有一定规律的,下标代表数据在数组中的序号。用一个数组名和下标惟一确定数组中的元素数组中的每一个元素都属于同一个数据类型6.1.2数组的基本概念6.2一维数组一维数组是数组中最简单的它的元素只需要用数组名加一个下标,就能惟一确定要使用数组,必须在程序中先定义数组6.2.1一维数组的定义6.2.1一维数组的定义1.一维数组定义的一般形式
类型符
数组名[常量表达式];数组名的命名规则和变量名相同如:inta[10];
数组名数组长度每个元素的数据类型a[0]a[1]a[2]a[3]…a[7]a[8]a[9]10个元素例如:
inta[10];//整型数组a有10个元素
floatb[100],c[20];//实型数组b有100个元素//实型数组c有20个元素6.2.1一维数组的定义(1)所有数组中数组元素的下标最小值都为0,下标最大值为数组定义时方括号中常量表达式的值减1。(2)数组类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。(3)数组名的命名规则应符合标识符的规定。2.一维数组定义的注意点6.2.1一维数组的定义(4)数组名不能与其它变量名相同。inta;floata[10];是错误的。(5)方括号中常量表达式表示数组元素的个数,常量表达式通常为一个数值常量,也可以为数字表达式,如:inta[2+3]表示数组a有5个元素,这5个元素分别为a[0],a[1],a[2],a[3],a[4]。6.2.1一维数组的定义(6)数组定义时不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。#defineN5voidmain()
{inta[3+2],b[7+N];//合法}inta[4+6];intn=10;inta[n];//不合法(7)允许在同一个定义语句中,说明多个数组和多个变量。inta,b,c,d,k1[10],k2[20];6.2.1一维数组的定义在定义数组并对其中各元素赋值后,就可以引用数组中的元素。6.2.2一维数组元素的引用一维数组元素的一般形式为:数组名[下标]其中:下标只能为整型常量或整型表达式。如果为实数时,则C编译将自动取整。例如:a[5]、a[i+j]、a[i++]都是合法的数组元素。如:a[0]=a[5]+a[7]-a[2*3]//合法intn=5,a[10];a[n]=20;//合法,此时的n为0~9,表示数组元素在C语言中必须先定义数组,然后才能使用该数组的下标变量,且只能单个或逐个使用下标变量,而不能一次引用整个数组。例如,要输出有10个元素的数组必须使用循环语句逐个输出各下标变量:for(i=0;i<10;i++)printf("%d",a[i]);而不能用一个语句输出整个数组。下面的写法是错误的:printf("%d",a);a为数组名6.2.2一维数组元素的引用【例6.1】从键盘输入10个整数,并将超过平均值的数打印出来。问题分析:
首先利用循环和数组将输入的数据存储起来,并求所有数据的和,然后再用循环输出超过平均值的各个数据。6.2.2一维数组元素的引用程序设计:#include<stdio.h>voidmain(){inti,s,av,a[10];s=0;for(i=0;i<10;i++)//数组数据输入,并求和{scanf("%d",&a[i]);s=s+a[i];}6.2.2一维数组元素的引用程序设计:av=s/10;//求平均值for(i=0;i<10;i++)//数组元素超过平均值时,输出{if(a[i]>av)printf("%d",a[i]);
}printf("\n");}6.2.2一维数组元素的引用6.2.3一维数组的输入/输出一维数组的初始化数组的初始化是指在数组定义时给数组元素赋予初值(1)一维数组初始化的一般形式类型说明符数组名[常量表达式]={值1,值2,……,值n};其中:在“{}”中的各数据值即为各元素的初值,各值之间用逗号间隔。例如:inta[10]={0,1,2,3,4,5,6,7,8,9};相当于:inta[10];a[0]=0;a[1]=1;……;a[9]=9;(2)一维数组初始化的规定①可以只给部分元素赋初值。当“{}”中值的个数少于元素个数时,只给前面部分元素赋初值。②只能给元素逐个赋初值,不能给数组整体赋初值。③如果给全部元素赋初值,则在数组说明中,可以不给出数组元素的个数。例如:inta[10]={0,1,2,3,4};表示只给a[0]~a[4]5个元素赋初值,而后面的a[5]~a[9]这5个元素自动赋以0值。例如,给10个元素全部赋1值,只能写为:inta[10]={1,1,1,1,1,1,1,1,1,1};而不能写为:inta[10]=1;例如:inta[5]={1,2,3,4,5};可写为:inta[]={1,2,3,4,5};6.2.3一维数组的输入/输出在定义数组的同时,给各数组元素赋值inta[10]={0,1,2,3,4,5,6,7,8,9};inta[10]={0,1,2,3,4};相当于inta[10]={0,1,2,3,4,0,0,0,0,0};inta[10]={0,0,0,0,0,0,0,0,0,0};相当于inta[10]={0};inta[5]={1,2,3,4,5};可写为inta[]={1,2,3,4,5};6.2.3一维数组的输入/输出一维数组的输入【例6.2】输入10个数据,求其中的最大数及其位置。问题分析:
本例程序中用数组a存放10个数,变量max存放最大值,变量p存放最大值的位置。先输入10个数到数组a中,然后把a[0]作为最大数送入max中,将1送到p中;再将a[1]到a[9]逐个与max中的内容比较,若比max的值大,则把该下标变量的值及下标加1送入max和p中。因此,max总是在已比较过的下标变量中为最大者,p为最大值的位置。比较结束时,输出max和p的值。#include<stdio.h>voidmain(){inti,max,p,a[10];printf("请输入10个数:");for(i=0;i<10;i++)//数组数据输入
scanf("%d",&a[i]);for(i=0;i<10;i++)//数组数据输出
printf("%d",a[i]);//找最大值及其位置}一维数组的输入【例6.3】输入10个数据,按逆序输出这10个数据。简化:利用数组下标对数组元素赋值,对10个数组元素依次赋值为、0,1,2,3,4,5,6,7,8,9一维数组的输入#include<stdio.h>voidmain(){inti,a[10];for(i=0;i<=9;i++)a[i]=i;for(i=9;i>=0;i--)printf("%d",a[i]);printf("\n");}使a[0]~a[9]的值为0~90123456789a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]一维数组的输出#include<stdio.h>voidmain(){inti,a[10];for(i=0;i<=9;i++)a[i]=i;for(i=9;i>=0;i--)printf("%d",a[i]);printf("\n");}先输出a[9],最后输出a[0]0123456789a[0]a[1]a[2]a[3]a[4]a[5]a[6]a[7]a[8]a[9]一维数组的输出
【思考】用数组处理求Fibonacci数列问题。解题思路:如果用数组处理,每一个数组元素代表数列中的一个数,依次求出各数并存放在相应的数组元素中。一维数组的输出#include<stdio.h>voidmain(){inti;intf[20]={1,1};for(i=2;i<20;i++)f[i]=f[i-2]+f[i-1];for(i=0;i<20;i++){if(i%5==0)printf("\n");printf("%12d",f[i]);}printf("\n");}6.3二维数组2456184712431600234627573045201817252020245814361427117510461976147720181分队2分队3分队队员1队员2队员3队员4队员5队员6如:floatpay[3][6];二维数组元素有两个下标,以标识它在数组中的位置,所以也称为双下标变量。C语言中允许构造二维数组。二维数组定义的一般形式为:
类型符数组名[常量表达式][常量表达式];其中:
常量表达式1表示第一维下标的长度,也就是行数
常量表达式2表示第二维下标的长度,也就是列数。如:inta[3][4];floatb[5][10];6.3.1二维数组的定义二维数组可被看作是一种特殊的一维数组:
它的元素又是一个一维数组例如,把a看作是一个一维数组,它有3个元素:a[0]、a[1]、a[2]每个元素又是一个包含4个元素的一维数组a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]a[0]a[1]a[2]6.3.1二维数组的定义a[0][0]a[0][1]a[0][2]a[0][3]a[1][0]a[1][1]a[1][2]a[1][3]a[2][0]a[2][1]a[2][2]a[2][3]逻辑存储顺序:内存存储顺序:在C语言中,二维数组中的元素是按行存放的。6.3.1二维数组的定义二维数组元素也称为双下标变量,表示形式为:
数组名[下标][下标]如:b[1][2]=a[2][3]/2;//合法for(i=0;i<m;i++)printf("%d,%d\n",a[i][0],a[0][i]);//合法6.3.2二维数组元素的引用6.3.3二维数组的输入输出1.二维数组的初始化(1)二维数组初始化的方法二维数组初始化是在类型说明时给各数组元素赋以初值。二维数组可按行分段赋值,也可按行连续赋值。①按行分段赋值
inta[5][3]={
{80,75,92},{61,65,71},{59,63,70},{85,87,90},{76,77,85}};②按行连续赋值
inta[5][3]={80,75,92,61,65,71,59,63,70,85,87,90,76,77,85};(2)二维数组初始化赋值的说明①可以只对部分元素赋初值,未赋初值的元素自动取0值。例如:inta[3][3]={{1},{2},{3}};对每一行的第一列元素赋值,未赋值的元素取0值。赋值后各元素的值为:100200300inta[3][3]={{0,1},{0,0,2},{3}};赋值后的元素值为:010002300②如对全部元素赋初值,则第一维的长度可以不给出。例如:inta[3][3]={1,2,3,4,5,6,7,8,9};可以写为:inta[][3]={1,2,3,4,5,6,7,8,9};inta[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};inta[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};inta[3][4]={{1},{5},{9}};等价于inta[3][4]={{1,0,0,0},{5,0,0,0},{9,0,0,0}};inta[3][4]={{1},{5,6}};相当于inta[3][4]={{1},{5,6},{0}};二维数组的初始化6.3.3二维数组的输入输出2.二维数组的输入同一维数组类似,也可以在程序执行过程中,对二维数组作动态输入,这时可用双重循环配合scanf()函数逐个输入二维数组元素的值。3.二维数组的输出同一维数组类似,也可以在程序执行过程中,要输出二维数组中所有元素,这时可用双重循环结构配合printf()函数逐个输出二维数组元素的值。6.3.3二维数组的输入输出【例6.4】一个学习小组有5位学生,每位学生有3门课程的考试成绩,如下表所示,求每位学生的平均成绩。
姓名高等数学大学物理程序设计张明807890王浩667179李琴858892赵飞778690周正6881796.3.3二维数组的输入输出
课程(1)问题分析设用一个二维数组a[5][3]存放5位学生3门课的成绩,再用一个一维数组b[5]存放所求得的每位学生的平均成绩。
课程姓名高等数学大学物理程序设计a[0]a[0][0]=80a[0][1]=78a[0][2]=90a[1]667179a[2]858892a[3]778690a[4]688179平均成绩b[0]a[0][3]6.3.3二维数组的输入输出#include<stdio.h>voidmain(){inti,j,s,b[5],a[5][3];//数组与变量的定义
printf("请输入学生的成绩:\n");for(i=0;i<5;i++){s=0;for(j=0;j<3;j++) {scanf("%d",&a[i][j]);//二维数组数据的输入,5行3列
s=s+a[i][j];//求二维数组每行元素之和}b[i]=s/3.0;//求二维数组每行元素的平均值
}for(i=0;i<5;i++)//输出二维数组,按5行4列格式{for(j=0;j<3;j++)printf("%d",a[i][j]);
printf("%d\n",b[i]);}}(2)程序设计思考:若直接定义一个二维数组a[5][4],前3列为课程成绩,最后一列为平均成绩,如何修改程序?a[5][4];a[i][3]=s/3.0;4字符串是用双撇号“"”作为定界符的一个字符序列,如:"a"、"Cprogram"等。在C语言中没有专门的字符串变量,通常用一个字符数组来存放一个字符串。6.4字符串及其处理用来存放字符数据的数组是字符数组。字符数组中的一个元素存放一个字符。定义字符数组的方法与定义数值型数组的方法类似前面介绍字符串常量时,已说明字符串总是以‘\0’作为串的结束符。因此,当把一个字符串存入一个数组时,也把结束符‘\0’存入数组,并以此作为该字符串是否结束的标志。6.4.1字符串及其结束标志
6.4字符串及其处理
字符串的长度表示字符数组的实际长度,C语言规定了字符串结束标志'\0'。'\0'—代表ASCII码为0的字符,是一个“空操作符”用它作为字符串结束标志不会产生附加的操作或增加有效字符,只起一个供辨别的标志。6.4字符串及其处理6.4.1字符串及其结束标志
6.4.1字符串及其结束标志
C语言允许用字符串的方式对数组作初始化赋值。例如:charc[]={'c','','p','r','o','g','r','a','m','\0'};charc[]={"Cprogram"};charc[]="Cprogram";C
program\0数组c在内存中的实际存放情况:'\0'为字符串结束标志,由系统自动加上。charc[10]={"China"};可写成charc[10]="China";从c[5]开始,元素值均为\0只显示printf("%s",c);China\0\0\0\0\0如果一个字符数组中包含多个'\0',则遇第一个'\0'时输出就结束6.4.1字符串及其结束标志
字符数组的输入输出可以有两种方法:
逐个字符输入输出(%c)
整个字符串一次输入输出(%s)输出的字符中不包括结束符'0'用%s输出字符串时,printf函数中的输出项是字符数组名,不是数组元素名6.4.2字符串的输入/输出
字符数组的输入输出可以有以下两种方法:1、用“%c”格式符将字符逐个输入或输出;
#include<stdio.h>voidmain(){inti;charch[]="cprogram.";//定义字符数组,并赋值字符串for(i=0;ch[i]!='0';i++)
printf("%c",ch[i]);//输出字符串}数组元素6.4.2字符串的输入/输出
2、用“%s”格式符,将整个字符串一次性输入或输出。#include<stdio.h>voidmain(){charch[]="cprogram.";//定义字符数组,并赋值字符串
printf("%s\n",ch);//输出字符串}数组名6.4.2字符串的输入/输出
#include<stdio.h>voidmain(){charst[15];//定义字符数组
printf("请输入一个字符串:\n");scanf("%s",st);//输入字符串
printf("%s\n",st);//输出字符串}两处均为数组名,表示首地址注意:1、对一个字符数组,如果不作初始化赋值,则必须说明数组长度。2、当用scanf函数输入字符串时,字符串中不能含有空格,否则将以空格作为串的结束符。6.4.3常用字符串处理函数C语言提供了丰富的字符串处理函数。用于输入输出的字符串函数,在使用前应包含头文件<stdio.h>,使用其它字符串函数则应包含头文件。<string.h>1.字符串输出函数puts格式:puts(字符数组名)功能:把字符数组中的字符串输出到显示器,即在屏幕上显示该字符串。#include<stdio.h>voidmain(){charc[]="BASIC\nVC++6.0";//定义字符数组,并赋值字符串puts(c);//输出字符数组}注意:'\n'与'\0'的区别'\n'—回车换行'\0'—字符串结束标志2.字符串输入函数gets格式:gets(字符数组名)功能:从标准输入设备键盘上输入一个字符串。本函数得到一个函数值,即为该字符数组的首地址。例如:#include<stdio.h>voidmain(){charst[15];//定义字符数组
printf("请输入一个字符串:");
gets(st);//输入字符数组
puts(st);//输出字符数组}6.4.3常用字符串处理函数3.字符串连接函数strcat格式:strcat(字符数组名1,字符数组名2)功能:把字符数组2中的字符串连接到字符数组1中字符串的后面,并删去字符串1后的串标志'\0'。本函数返回值是字符数组1的首地址。例如:#include<stdio.h>#include<string.h>//使用字符串函数的头函数voidmain(){charst1[30]="我的名字是:";//定义字符数组st1,并赋值字符串
charst2[10];//定义字符数组st2printf("请输入你的姓名:");gets(st2);//输入字符数组st2
strcat(st1,st2);//将字符数组st2连接到字符数组st1中
puts(st1);//输出字符数组st1}6.4.3常用字符串处理函数4.字符串拷贝函数strcpy格式:strcpy(字符数组名1,字符数组名2)功能:把字符数组2中的字符串拷贝到字符数组1中。字符串结束标志'\0'也一同拷贝。字符数组名2也可以是一个字符串常量,这时相当于把一个字符串赋予一个字符数组。例如:#include<stdio.h>#include<string.h>//使用字符串函数的头函数voidmain(){charst1[15],st2[]="CLanguage";
strcpy(st1,st2);//将字符数组st2中的字符复制到字符数组st1puts(st1);printf("\n");}6.4.3常用字符串处理函数5.字符串比较函数strcmp格式:strcmp(字符数组名1,字符数组名2)功能:按照ASCII码值顺序比较两个字符数组中的字符,并由函数返回值返回比较结果。字符串比较规则:将两个字符串中的字符从左到右逐个比较ASCII码值的大小,如果遇到字符的ASCII值大,则对应那个字符串就大;如果两个字符串完全相同,则这两个字符串就相等。字符串比较的结果由函数值带回:①字符串1=字符串2,返回值=0;②字符串1>字符串2,返回值>0;③字符串1<字符串2,返回值<0。6.4.3常用字符串处理函数#include<stdio.h>#include<string.h>voidmain(){intk;charst1[15],st2[]="CLanguage";printf("请输入一个字符串:");gets(st1);
k=strcmp(st1,st2);//将字符数组st1与st2中的字符进行比较
if(k==0)printf("st1=st2\n");//比较结果为0时,两个字符串相等
if(k>0)printf("st1>st2\n");//比较结果大于0时,st1>st2if(k<0)printf("st1<st2\n");//比较结果小于0时,st1<st2}6.求字符串长度函数strlen格式:strlen(字符数组名)功能:求字符串的实际长度(不含字符串结束标志'\0'),并作为函数返回值。例如:#include<stdio.h>#include<string.h>voidmain(){intk;charst[]="C语言程序设计";k=strlen(st);//求字符串的长度,一个汉字的长度为2,不含结束标志
printf("字符串的长度是:%d\n",k);}7.转换大写字母为小写字母函数strlwr格式:strlwr(字符数组名)功能:将字符串中的大写字母转换为小写字母。例如:printf("%s\n",strlwr("ThisisaBOOK."));8.转换小写字母为大写字母函数strupr格式:strupr(字符数组名)功能:将字符串中的小写字母转换为大写字母。例如:printf("%s\n",strupr("Thisisabook."));6.5程序设计举例【例6.5】采用顺序查找法在任意给定的10数中找出要查找的数。(1)算法分析首先从键盘输入一个要查找的数,然后将数组中每一个数依次与要查找的数进行比较,如果相等,则表明已经找到,找到时就退出循环;如果所有数与要查找的数都不相等,则说明要查找的数不存在。数组的典型应用:查找顺序查找:在数组a中查找是否存在数x?查找的方法一般有:顺序查找,折半查找两种。(2)程序设计#include<stdio.h>#defineN10voidmain(){inta[N],i,x;printf("请输入10个数据:\n");for(i=0;i<N;i++){printf("第%d个数据:",i+1);
scanf("%d",&a[i]);}printf("\n\n");printf("请输入要查找的数:\n");scanf("%d",&x);//输入要查找的数
for(i=0;i<N;i++)//将数组中的数据逐个与要找的数进行比较
if(x==a[i])break;//找到时,结束查找
if(i<N)//i<N时,说明是找到了,在循环体内跳出的printf("要查找的数是:a[%d]=%d\n",i,x);else//i>=N时,说明整个数组中没有等于要找的数printf("要查找的数%d不存在!\n",x);}
【例6.6】采用选择法排序将任意给定的10数按从小到大的顺序排列。(1)算法分析设已经在数组a中输入了10个整数,数组元素分别为a[0],a[1],……,a[9],且数组中的10个数据为:6,12,8,2,5,4,7,11,10,9。数组的典型应用:排序数组的典型应用:排序
排序的规律有升序(从小到大)和降序(从大到小)两种。排序的方法很多,常见的有:选择排序,冒泡排序、插入排序等。第1轮:把a[0]依次与a[1]~a[9]中的数比较,如果a[0]大,则进行交换;第2轮:把a[1]依次与a[2]~a[9]中的数比较,如果a[1]大,则进行交换;第3轮:把a[2]依次与a[3]~a[9]中的数比较,如果a[2]大,则进行交换;第4轮:把a[3]依次与a[4]~a[9]中的数比较,如果a[3]大,则进行交换;第5轮:把a[4]依次与a[5]~a[9]中的数比较,如果a[4]大,则进行交换;第6轮:把a[5]依次与a[6]~a[9]中的数比较,如果a[5]大,则进行交换;第7轮:把a[6]依次与a[7]~a[9]中的数比较,如果a[6]大,则进行交换;第8轮:把a[7]依次与a[8]~a[9]中的数比较,如果a[7]大,则进行交换;第9轮:把a[8]与a[9]中的数比较,如果a[8]大,则进行交换。数组的典型应用:选择法排序处理过程如下:初始数据:6,12,8,2,5,4,7,11,10,9第一轮后结果:2,12,8,6,5,4,7,11,10,9第二轮后结果:2,4,12,6,8,5,7,11,10,9第三轮后结果:2,4,5,12,8,6,7,11,10,9第四轮后结果:2,4,5,6,12,8,7,11,10,9第五轮后结果:2,4,5,6,7,12,8,11,10,9第六轮后结果:2,4,5,6,7,8,12,11,10,9第七轮后结果:2,4,5,6,7,8,9,12,11,10第八轮后结果:2,4,5,6,7,8,9,10,12,11第九轮后结果:2,4,5,6,7,8,9,10,11,12数组的典型应用:选择法排序
回顾前面所介绍的三个数的排序方法,可将该方法扩展到更多数的排序。
第1趟:把a[0]依次与a[1]~a[9]中的数比较;第2趟:把a[1]依次与a[2]~a[9]中的数比较;第3趟:把a[2]依次与a[3]~a[9]中的数比较;
……第8趟:把a[7]依次与a[8]~a[9]中的数比较;第9趟:把a[8]依次与a[9]比较;~a[9]i=0i=1i=2i=7i=8a[i]a[i+1]a[i]a[i+1]a[i]a[i+1]a[i]a[i+1]a[i]a[i+1]数组的典型应用:选择法排序#include<stdio.h>voidmain(){voida[10],i,j,t;printf("Input10numbers:\n");
for(i=0;i<10;i++)scanf("%d",&a[i]);
printf("\n");
for(i=0;i<9;i++)for(j=i+1;j<=9;j++)if(a[i]>a[j]){t=a[i];a[i]=a[j];a[j]=t;}
printf("Thesortednumbers:\n");
for(i=0;i<10;i++) printf("%d",a[i]);}思考:能否改进,以减少交换次数?for(i=0;i<9;i++)
{p=i;//p指向第i个数
for(j=i+1;j<10;j++)if(a[j]<a[p])p=j;//第j个数小于p指的数时,p向第j个数
if(i!=p)//p的值变化时,交换
{t=a[i];a[i]=a[p];a[p]=t;}}【例6.7】采用冒泡法排序将任意给定的10数按从小到大的顺序排列。解题思路:排序的规律有两种:一种是“升序”,从小到大;另一种是“降序”,从大到小把题目抽象为:“对n个数按升序排序”采用起泡法排序,下面以6个数为例,显示动态比较和交换过程。数组的典型应用:冒泡法排序985420895420859420854920854290854209大数沉底,小数起泡a[0]a[1]a[2]a[3]a[4]a[5]for(i=0;i<5;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}854209584209548209542809542089for(i=0;i<4;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}a[0]a[1]a[2]a[3]a[4]a[5]542089452089425089420589for(i=0;i<3;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}a[0]a[1]a[2]a[3]a[4]a[5]420589240589204589for(i=0;i<2;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}a[0]a[1]a[2]a[3]a[4]a[5]204589024589for(i=0;i<1;i++)if(a[i]>a[i+1]){t=a[i];a[i]=a[i+1];a[i+1]=t;}a[0]a[1]a[2]a[3]a[4]a[5]for(i=0;i<5;i++)if(a[i]>a[i+1]){……}for(i=0;i<4;i++)if(a[i]>a[i+1]){……}for(i=0;i<1;i++)if(a[i]>a[i+1]){……}……for(i=0;i<5-j;i++)if(a[i]>a[i+1]){……}for(j=0;j<5;j++)inta[10];inti,j,t;printf("input10numbers:\n");for(i=0;i<10;i++)scanf("%d",&a[i]);printf("\n");for(j=0;j<9;j++) for(i=0;i<9-j;i++) if(a[i]>a[i+1]) {t=a[i];a[i]=a[i+1];a[i+1]=t;}printf("thesortednumbers:\n");for(i=0;i<10;i++)printf("%d",a[i]);printf("\n");典型问题:折半查找【例6.8】采用折半查找法在任意给定的10个数中找出要查找的数。重复工作:①求中点m=(b+t)/2;②判断a[m]是否等于x,如果等于x,则退出循环,否则继续下一步;③判断x>a[m]?如果成立,说明x可能在数组a的后一半(a[m+1],a[t])中,否则可能在数组a的前一半(a[t],a[m-1])中;④转①。(1)算法分析设一维数组a中的数据是有序的(升序),b和t是一维数组a下标的最小值和最大值。b=m+1开始结束输入a数组,xa[m]=xYNx>a[m]YNm=(b+t)/2判断加输出t=m-1对数组a排序b=0,t=9b<=tYN(3)程序设计#include<stdio.h>voidmain(){inta[10],x,i,j,m,b,t;printf("请输入10个数:\n");for(i=0;i<10;i++)scanf("%d",&a[i]);printf("输入要查找的数:\n");scanf("%d",&x);//输入要查找的数
for(i=0;i<9;i++)//选择法排序
for(j=i+1;j<10;j++)if(a[i]>a[j])
{t=a[i];a[i]=a[j];a[j]=t;}典型问题:折半查找(3)程序设计b=0;t=9;//设查找的区间的下限和上限
while(b<=t)//当下限小于或等于上限时,进行循环
{m=(b+t)/2;
if(x==a[m])break
if(x>a[m])//若要找的数大于中点元素,则在右一半找b=m+1;else//若要找的数小于中点元素,则在左一半找t=m-1;}if(b<=t)//若下限小于或等于上限时,则找到,否则没有找到
printf("要查找的数a[%d]=%d\n",m,x);elseprintf("%d要查找的数不存在!\n",x);}【例6.9】用筛选法求100以内的素数。算法分析:(1)定义一维数组a,其初值为:2,3,……,100;(2)若a[k]不为0,则将该元素的倍数的数组元素置为0;(3)数组a中不为0的元素,均为素数。典型问题:求素数
#include<math.h>voidmain(){intk,j,a[101],l=0;
for(k=2;k<101;k++)a[k]=k;for(k=2;k<sqrt(101);k++)for(j=k+1;j<101;j++)
if(a[k]!=0&&a[j]!=0) if(a[j]%a[k]==0)a[j]=0;for(k=2;k<101;k++){if(a[k]!=0)printf("%10d",a[k]);l=l+1;if(l%5==0)printf("\n");}}赋初值,数组值等于下标若a[k]不为0,则将该元素的倍数的数组元素置为0数组a中不为0的元素均为素数
【例6.4】
将一个二维数组行和列的元素互换,存到另一个二维数组中。典型问题:矩阵处理解题思路:可以定义两个数组:数组a为2行3列,存放指定的6个数数组b为3行2列,开始时未赋值将a数组中的元素a[i][j]存放到b数组中的b[j][i]元素中用嵌套的for循环完成典型问题:矩阵处理#include<stdio.h>voidmain(){inta[2][3]={{1,2,3},{4,5,6}};intb[3][2],i,j;printf("arraya:\n");for(i=0;i<=1;i++){for(j=0;j<=2;j++){printf("%5d",a[i][j]);b[j][i]=a[i][j];}printf("\n");}//处理a的一行中各元素//处理a中某一列元素//输出a的各元素//a元素值赋给b相应元素
printf("arrayb:\n");for(i=0;i<=2;i++){for(j=0;j<=1;j++)printf("%5d",b[i][j]);printf("\n");}}
//输出b的各元素典型问题:矩阵处理
【例6.10】有一个3×4的矩阵,要求找出其中值最大的那个元素的值,以及其所在的行号和列号。解题思路:采用“打擂台算法”先找出任一人站在台上,第2人上去与之比武,胜者留在台上第3人与台上的人比武,胜者留台上,败者下台以后每一个人都是与当时留在台上的人比武,直到所有人都上台比为止,最后留在台上的是冠军典型问题:矩阵处理
解题思路:采用“打擂台算法”先把a[0][0]的值赋给变量max,并记当前最大值所在行和列为0;max用来存放当前已知的最大值,row和colum用来存入最大值所在的行号和列号;将数组中的每个数组元素依次与max比较,如a[0][1]与max比较,如果a[0][1]>max,则表示a[0][1]是已经比过的数据中值最大的,把它的值赋给max,取代了max的原值,同时修改行号和列号;以后依此处理,最后max就是最大的值,row和colum的值就是最大值所在的位置。
fori=0to2
forj=0to3max=a[i][j]row=Icolum=ja[i][j]>max真
max=a[0][0]输出:max,row,colum假……
inti,j,row=0,colum=0,max;inta[3][4]={{1,2,3,4},{9,8,7,6},{-10,10,-5,2}};max=a[0][0];for(i=0;i<=2;i++)for(j=0;j<=3;j++)if(a[i][j]>max){max=a[i][j];row=i;colum=j;}printf("max=%d\nrow=%d\ncolum=%d\n",max,row,colum);……思考:1.求一个3*3的整型矩阵对角线元素(周边元素)之和2.输出杨辉三角形。111121133114641……典型问题:矩阵处理对角线及周边元素之和#defineN4voidmain(){inta[N][N],i,j;……//定义sum1,sum2并赋初值,二维数组赋值并输出)for(i=0;i<N;i++)//计算对角线元素之和 for(j=0;j<N;j++)
if(i==j||i+j==N-1)//满足条件的才相加 sum1+=a[i][j];printf("两条对角线上的元素之和为:%5d\n",sum1);for(i=0;i<N;i++) for(j=0;j<N;j++)
if(i==0||i==N-1||j==0||j==N-1) sum2+=a[i][j];printf("四周靠边的元素之和为:%5d\n",sum2);}杨辉三角形#defineN8voidmain(){inta[N][N],i,j;for(i=0;i<N;i++)//N为符号常量,由#define定义{a[i][0]=1;a[i][i]=1; for(j=1;j<i;j++) a[i][j]=a[i-1][j-1]+a[i-1][j];}for(i=0;i<N;i++){ for(j=0;j<=i;j++)//仅输出下三角的数组元素printf("%5d",a[i][j]);printf("\n");}}for(i=0;i<N;i++){for(j=0;j<=i;j++)if()a[i][j]=0; elsea[i][j]=a[i-1][j-1]+a[i-1][j];}
字符例1:输入一行字符,编写程序分别统计各个英文字母出现的次数(不区分字母大小写)。解题思路:统计26个字母中每个字母出现的次数,可定义数组存放每个字符的个数,如zmc[26],并初始化为0从第1个字符开始逐个字符进行检查,判断此字符是否是大写字母,如果是'A',就将zmc
[0]加1如果是'B',就将zmc
[1]加1如果是'C',就将zmc
[2]加1如果是ch,就将zmc
[?]加1否则,判断此字符是否是小写字母,如果是'a',就将zmc
[0]加1典型问题:字符处理统计各个英文字母出现的次数—部分代码while((ch=getchar())!='\n') { if(ch>='A'&&ch<='Z') zmc[ch-'A']++; elseif(ch>='a'&&ch<='z') zmc[ch-'a']++; }for(i=0;i<26;i++)
printf("%c:%d\n",i+'a',zmc[i]); charch;intzmnum=0,kgnum=0,sznum=0,other_num=0;while((ch=getchar())!='\n') {if(ch>='a'&&ch<='z'||ch<='z'&&ch>='a')zmnum++;elseif(ch=='')kgnum++;elseif(ch>='0'&&ch<='9')sznum++;elseother_num++; }isalpha(ch)(isspace(ch))(isdigit(ch))函数外部加#include<ctype.h>
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 小数点位置移动引起小数大小的变化课件
- 新生儿气道管理课件
- 焊接工艺课件-焊条电弧焊V形坡口板对接横焊
- 《慢阻肺gold指南》课件
- 《草帽图解析话术》课件
- 《心理学章》课件
- 【课件】发现你的优势
- 【大学课件】建筑电气安装工程定额计价
- 单位管理制度展示汇编【人力资源管理】
- 单位管理制度展示大全职工管理篇
- 无锡市区2024-2025学年四年级上学期数学期末试题一(有答案)
- GB/T 45014-2024聚合物基复合材料层压板紧固件拉脱阻抗试验方法
- 传播学(东北林业大学)知到智慧树章节答案
- 2024年安全员之A证考试题库及完整答案(网校专用)
- 血液净化中心院内感染控制课件
- 统编版2024-2025学年三年级上册语文期末情景测试卷 (无答案)
- 年产1.5万吨长链二元酸工程建设项目可研报告
- 绩效考核办法1
- 【MOOC】外科护理学-中山大学 中国大学慕课MOOC答案
- 年度学校办公室工作总结
- 2025版国家开放大学法律事务专科《民法学(2)》期末纸质考试总题库
评论
0/150
提交评论