数组二

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
				子序列 不要求连续,前后关系要和原序列一致 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值