0.回顾一下 一维数组
定义格式:
元素类型 数组名[数组元素的个数]
例子:
int a[4];//定义了一个数组 名为a 里面有4个int类型的元素
//a[0] a[1] a[2] a[3]
//在定义数组a的同时,也声明了一个新类型
"像a这样的类型"
typeof(a) ==> int[4]
一个问题:
定义3个a这样的类型,该如何定义呢?
数组
typeof(a) b[3];//定义了一个数组。名为b,里面
含有3个typeof(a)这种类型的元素。
int[4] b[3];
===>int b[3][4];//二维数组
但是:
b的含义是: int[4] b[3]
1.二维数组
由上面的推导过程可以得到:
C语言中,二维数组实际上就是一个一维数组,只不过
该一维数组中的每个元素又是一个一维数组。
int b[3][4];<==>int[4] b[3];
数组名为b,里面有3个元素;
b[0]_ _ _ _->里面包含有4个int,b[0]又是一个数组,数组名为b[0]
b[1]_ _ _ _->里面包含有4个int,b[1]又是一个数组,数组名为b[1]
b[2]_ _ _ _->里面包含有4个int,b[2]又是一个数组,数组名为b[2]
"三行四列" "矩阵"
1.1 二维数组定义
类型说明符 数组名[行数][列数];//从“矩阵角度”来看二维数组
“类型说明符”:二维数组中元素的类型!!!!不是数组的类型!!!
C语言中任意的合法的类型都可以
“行数” “列数”:常量表达式
1.2二维数组的引用
数组元素的引用:数组名[下标]
例子:
int a[3][4];=>int[4] a[3];
a[0]_ _ x _ a[0]是一个数组名,里面有4个int类型的元素
a[1]_ _ _ _
a[2]_ _ _ _
要访问上面的元素x,它的下标是2
a[0][2]
引用二维数组的元素和引用普通变量是一模一样
它也有左值和右值;
a[0][2]=1024;//a[0][2]代表的元素的地址,“左值”
int b=a[0][2];//a[0][2]代表的是元素的值,“右值”
1.3二维数组元素的存放
int a[3][4];==>int[4] a[3]
a[0]_ _ _ x
a[1]y _ _ _
a[2]_ _ _ _
按行存放,即先顺序存放第一行的元素,然后再存放第二行的顺序,...
像上面的元素x 和 y的地址是相邻的。
1.4二维数组的初始化
你在定义二维数组的时候,可以指定每个元素或者部分元素的初始值的。
数组初始化用{};
a.分行给二维数组赋处置
int a[3][4]={
{1,2,3,4},//a[0]也是一个数组所以可以用{}
{5,6,7,8},
{9,10,11,12}
};
b.将所有的元素写在一个{}内,按数组的排列顺序一一给各个元素初始化。
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
c.对部分元素赋初值,其余的元素自动置0
int a[3][4]={
{1,2},
{5,6},
{9}
};
<=>
int a[3][4]={
{1,2,0,0},
{5,6,0,0},
{9,0,0,0}
};
=>a[0][2]=0
d.如果对全部元素都赋初始值,则定义二维数组的时候对第一维的长度
可以省略的,但是第二维的长度不能省略。
int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};<-----------------
==>int[4] a[]={1,2,3,4,5,6,7,8,9,10,11,12};
NOTE:
只有在数组定义时候,才能全部赋值数组元素
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
int a[3][4];
a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};//error!!!!!!!!!
练习:
1.定义一个二维数组,从键盘上按行输入每一个元素的值。
2.定义一个二维数组,从键盘上按行输入数组每个元素;
然后求该二维数组的和,最大值,最小值。
3.把一个二维数组,列行值互换
a[3][4] --> b[4][3]
4.把一个二维数组a[4][4]的对角线的元素的和输出
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
PS:请从键盘上输入 时间:半小时
5.(附加)定义一个二维数组,从键盘上按行输入数组每个元素;
由小到大对每个元素进行排序。
2.关于数组的类型
关于xxx的类型,是一个给它的定性。
它是个东西
int a[4];
//a是一个含有4个int类型元素的数组。
typeof(a) ==> int[4]
float b[10];
//b是个一个含有10个float类型元素的数组
typeof(b) ==> float[10]
int a[3][4];==>int[4] a[3]
//a是一个含有3个元素且每个元素又含有4个int类型 的数组
a是一个含有3个元素且每个元素又是一个数组(int[4])的数组
typeof(a)
int[4] [3]
作业:
1.求一个二维数组中山顶元素的个数
山顶:此处比周围高,就是山顶
算法思路:
遍历每一个元素,如果此元素比周围的元素都打,那么它
就是一个山顶
int a[M][N];
int b[M][N]={0};//b数组所有的元素和a数组是一一对应的
//0表示该元素是山顶元素
"遍历"
for(i=0;i<M;i++)
{
for(j=0;j<N;j++)
{
if(b[i][j]==0)
{
a[i][j]?
if(它是山顶元素)
{
count++;
}
//将这个山顶元素 对应的 b数组里面 那个元素
//周围的元素全部置成1
}
}
}
它是山顶元素==>
1.它比周围元素都要大
它比上面大&&它比下面大&&它比左边大&&它比右边大
2.它比上面大
上面不存在||比上面大
i==0 || (a[i][j]>a[i-1][j])
3.它比下面大
i==(M-1)||(a[i][j]>a[i+1][j])
...
...
if(它是山顶元素)
if(1&&2&&3&&4)
2.求一个二维数组中的鞍点(行中最大,列中最小)
王飘
先找行中最大
判断是不是列中最小
输出鞍点 是不是应该记录鞍点的下标
int a[M][N];
int max_b;
int max;
for(i=0;i<M;i++)//遍历行
{
max=a[i][0];
max_b=0;
//遍历当前行
for(j=0;j<N;j++)
{
if(a[i][j]>max)
{
max=a[i][j];
//记录下标
max_b=j;
}
}
//遍历最大值的当前行 看一下是不是当前列
//最小值
for(j=0;j<M;j++)
{
if(a[j][max_b]<max)
{
break;
}
}
if(M==j)
{
printf("a[%d,%d]是鞍点\n",i,max_b);
}
}
3.小明喜欢占座位,教室有M行N列,小明每次还要跟宿舍的
同学占座位。宿舍有K个人(包含他自己)(K<N)。
每次去教室的时候,教室里面的座位可能有人了或者已经
被人占了。
然后小明宿舍的几个人每次都必须坐一起,一排。
求有多少种占座的可能
算法一:
数连续的0 == k 就是一种占座的可能
0 0 0 0 k==3 2种
0 0 0 0 0 3种
0 0 0 0 0 0 4种
0 0 1 1 0 0 遇到1的时候是不是要重新数0的个数
int n=0;//占座的可能性
for(i=0;i<M;i++)
{
count=0;//连续的0的个数
for(j=0;i<N;j++)
{
if(a[i][j]==0)
{
count++;
}
else
{
count=0;
}
if(count>=k)
{
n++;
}
}
}
算法二:
0 0 0 0 1 0 0
a[i][j]为头的连续k个0,就为一种
for(i=0;i<M;i++)
{
for(j=0;i<N-K;j++)
{
s=0;
if(a[i][j]==0)
{
//看是否有连续的K个0
for(l=j+1;l<j+k;l++)//遍历后面的k-1个元素
{
s+=a[i][l];//求和
}
if(s==0)//看后面的k-1个元素的和是否为 0
{
n++;
}
}
}
}
4.将整数m插入到升序数组a中去,使得插入后的数组a仍然有序。
//要求 使用二分查找
5.最长上升子序列的长度
如:1 4 -3 -9 5 9 0
如:1,5,2,3,4,6,-5,-9,10,11
子序列 不要求连续,前后关系要和原序列一致
数组二
最新推荐文章于 2023-10-11 16:53:00 发布