ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

二维数组

2022-03-10 12:31:52  阅读:235  来源: 互联网

标签:int 元素 矩阵 二维 数组 include


二维数组
一、二维数组的定义
当一维数组元素的类型也是一维数组时,便构成了“数组的数组”,即二维数组。二维数组定义的一般格式:
数据类型 数组名[常量表达式1] [常量表达式2] ;
例如:int a[4][10];
a数组实质上是一个有4行、10列的表格,表格中可储存40个元素。第1行第1列对应a数组的a[0][0],第n行第m列对应数组元素a[n-1][m-1]。
说明:当定义的数组下标有多个时,我们称为多维数组,下标的个数并不局限在一个或二个,可以任意多个,如定义一个三维数组a和四维数组b:
int a[100][3][5];
int b[100][100][3][5];
多维的数组引用赋值等操作与二维数组类似。
二、二维数组元素的引用
二维数组的数组元素引用与一维数组元素引用类似,区别在于二维数组元素的引用必须给出两个下标。
引用的格式为:
<数组名>[下标1][下标2]
说明:显然,每个下标表达式取值不应超出下标所指定的范围,否则会导致致命的越界错误。
例如,设有定义:int a[3][5];
则表示a是二维数组(相当于一个3*5的表格),共有3*5=15个元素,它们是:
a[0][0] a[0][1] a[0][2] a[0][3] a[0][4]
a[1][0] a[1][1] a[1][2] a[1][3] a[1][4]
a[2][0] a[2][1] a[2][2] a[2][3] a[2][4]
因此可以看成一个矩阵(表格),a[2][3]即表示第3行第4列的元素。
三、二维数组的初始化
二维数组的初始化和一维数组类似。可以将每一行分开来写在各自的括号里,也可以把所有数据写在一个括号里。
例如:
int direct[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}
int direct[4][2] = {1,0,0,1,-1,0,0,-1} //尽量不要用
四、二维数组程序设计
例5.8 设有一程序

#include<cstdio>
#include<iostream>
#include<iomanip>
const int n=3;
using namespace std;
int a[n+1][n+1];
int main()
{
    for (int i=1; i<=n; ++i)
    {
      for (int j=1; j<=n; ++j)
        cin>>a[i][j];
    }
    for (int i=1; i<=n; ++i)
    {
        for (int j=1; j<=n; ++j) 
             cout<<setw(5)<<a[j][i];
        cout<<endl;
    }
    return 0;
}

程序的输入:

2 1 3
3 3 1
1 2 1
程序的输出:
2 3 1
1 3 2
3 1 1
例5.9 已知一个6*6的矩阵(方阵),把矩阵二条对角线上的元素值加上10,然后输出这个新矩阵。
【分析】 矩阵即表格,是一个二维数组,有6行6列共36个元素,每个矩阵都有二条对角线,本题难点在于对角线的元素怎么确定。

#include<iostream>
#include<iomanip>
using namespace std;
int a[7][7];
int main()
{
   for (int i=1; i<=6; ++i)	//输入矩阵元素
   for (int j=1; j<=6; ++j)
   cin>>a[i][j];
   for (int i=1; i<=6; ++i)	//更改对角线上元素的值
   for (int j=1; j<=6; ++j)
   if ((i==j)||(i+j==7)) a[i][j]+=10; //寻找对角线的特征
   for (int i=1; i<=6; ++i)	//输出6行6列的矩阵元素
   {
   for (int j=1; j<=6; ++j)
   cout<<setw(5)<<a[i][j];
   cout<<endl;
   }
   return 0;
}

例5.10 大部分元素是0的矩阵称为稀疏矩阵,假设有k个非0元素,则可把稀疏矩阵用K*3的矩阵简记之,其中第一列是行号,第二列是列号,第三列是该行、该列下的非0元素的值。如:

0 0 0 5 写简记成: 1 4 5 //第1行第4列有个数是5
0 2 0 0 2 2 2 //第2行第2列有个数是2
0 1 0 0 3 2 1 //第3行第2列有个数是1
试编程读入一稀疏矩阵,转换成简记形式,并输出。
【分析】 本题中需要解决的主要问题是查找非零元素并记忆位置。将原始矩阵存于数组a。转换后的矩阵存于数组b,当然b数组的行数可以控制在一个小范围内。

#include<iostream>
#include<iomanip>
const int n=3,m=5;
using namespace std;
int main()
{
    int a[n+1][m+1],b[101][4],k=0;
    for (int i=1; i<=n; ++i) //矩阵初始
    for (int j=1; j<=m; ++j) 
    cin>>a[i][j];
    for (int i=1; i<=n; ++i)
    for (int j=1; j<=m; ++j)
    if (a[i][j]!=0) //找到非零值,存储
    {
    ++k;
    b[k][1]=i;
    b[k][2]=j;
    b[k][3]=a[i][j];
    }
 for (int i=1; i<=k; ++i) //输出
    {
    for (int j=1; j<=3; ++j) 
cout<<setw(3)<<b[i][j];
    cout<<endl;
    }
    return 0;
}

运行结果:

输入: 0 0 0 0 5
    0 0 4 0 0
    1 0 0 0 1

输出: 1 5 5
2 3 4
    3 1 1
    3 5 1
例5.11 打印杨辉三角形的前10行。杨辉三角形如下图:

1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1 
[图5-1]         
【问题分析】观察图5-1,大家不容易找到规律,但是如果将它转化为图5-2,不难发现杨辉三角形其实就是一个二维表的小三角形部分,假设通过二维数组yh存储,每行首尾元素为1,且其中任意一个非首位元素yh[i][j]的值其实就是yh[i-1][j-1]与yh[i-1][j]的和,另外每一行的元素个数刚好等于行数。有了数组元素的值,要打印杨辉三角形,只需要控制好输出起始位置就行了。

#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
  int a[11][11];
   a[1][1]=1;	//设定第一行的值
  for (int i=2; i<=10; ++i)	//从第二行开始推
  
  a[i][1]=1; a[i][i]=1;	//设定每一行的首尾值为1
  for (int j=2; j<=i-1; ++j)	//当前行非首尾的数
  a[i][j]=a[i-1][j-1]+a[i-1][j]; //每个数等于上一行的二个数之和
  }
  for (int i=1; i<=10; i++)
  {
  if (i!=10) cout<<setw(30-3*i)<<" ";	//控制每行的起始位置,即空格数量
  for (int j=1; j<=i; j++) cout<<setw(6)<<a[i][j];
  cout<<endl; 
  }
  return 0;
} 

例5.12 输入一串字符,字符个数不超过100,且以“.”结束。 判断它们是否构成回文。

【分析】所谓回文指从左到右和从右到左读一串字符的值是一样的,如12321,ABCBA,AA等。先读入要判断的一串字符(放入数组letter中),并记住这串字符的长度,然后首尾字符比较,并不断向中间靠拢,就可以判断出是否为回文。
程序如下:

#include<iostream>
using namespace std;
int main()
{    char ch,letter[101];
    int i=0,j=1;
    cout<<"Input a string:";
    cin>>ch;
    while (ch!='.')				//读入一个字符串以'.'号结束
    {
      ++i;
      letter[i]=ch;
      cin>>ch;
    }
    while ((j<i)&&(letter[j]==letter[i]))		//判断它是否是回文
    {
        --i; ++j;
    }
    if (j>=i) cout<<"Yes"<<endl;
       else   cout<<"No"<<endl;
    return 0;
}

例5.13 蛇形填数

  在n*n方阵里填入1,2,3,…,n*n,要求填成蛇形。例如n=4时方阵为:
  10 11 12 1
  9 16 13 2
  8 15 14 3
  7 6 5 4
  上面的方阵中,多余的空格只是为了便于观察规律,不必严格输出,n<=8。
【分析】:
  类比数学中的矩阵,我们可以用一个所谓的二维数组来储存题目中的方阵。只需声明一个int a[MAXN][MAXN],就可以获得一个大小为MAXN×MAXN的方阵。在声明时,两维的大小不必相同,因此也可以声明int a[30][50]这样的数组,第一维下标范围是0,1,2,…,29,第二维下标范围是0,1,2,…,49。
让我们从1开始依次填写。设“笔”的坐标为(x,y),则一开始x=0,y=n-1,即第0行,第n-1列(别忘了行列的范围是0到n-1,没有第n列)。“笔”的移动轨迹是:下,下,下,左,左,左,上,上,上,右,右,下,下,左,上。总之,先是下,到不能填了为止,然后是左,接着是上,最后是右。“不能填”是指再走就出界(例如4→5),或者再走就要走到以前填过的格子(例如12→13)。如果我们把所有格子初始为0,就能很方便地加以判断。

二维数组
例5.13  蛇形填数
     在n*n方阵里填入1,2,3,…,n*n,要求填成蛇形。例如n=4时方阵为:
    10 11 12  1
     9  16 13  2
     8  15 14  3
     7    6   5  4
    上面的方阵中,多余的空格只是为了便于观察规律,不必严格输出,n<=8。
【分析】:
    类比数学中的矩阵,我们可以用一个所谓的二维数组来储存题目中的方阵。只需声明一个int a[MAXN][MAXN],就可以获得一个大小为MAXN×MAXN的方阵。在声明时,两维的大小不必相同,因此也可以声明int a[30][50]这样的数组,第一维下标范围是0,1,2,…,29,第二维下标范围是0,1,2,…,49。
    让我们从1开始依次填写。设“笔”的坐标为(x,y),则一开始x=0,y=n-1,即第0行,第n-1列(别忘了行列的范围是0到n-1,没有第n列)。“笔”的移动轨迹是:下,下,下,左,左,左,上,上,上,右,右,下,下,左,上。总之,先是下,到不能填了为止,然后是左,接着是上,最后是右。“不能填”是指再走就出界(例如4→5),或者再走就要走到以前填过的格子(例如12→13)。如果我们把所有格子初始为0,就能很方便地加以判断。
#include<cstdio>
#include<cstring>
#define MAXN 10
int a[MAXN][MAXN];
int main()
{
	int n,x,y,tot=0;
	scanf("%d",&n);
	memset(a,0,sizeof(a));
	tot=a[x=0][y=n-1]=1;
	while (tot<n*n)

       {
             while (x+1<n && !a[x+1][y]) a[++x][y]=++tot;
             while (y-1>=0 && !a[x][y-1]) a[x][--y]=++tot;
             while (x-1>=0 && !a[x-1][y]) a[--x][y]=++tot;
             while (y+1<n && !a[x][y+1]) a[x][++y]=++tot;
        }
        for(x=0;x<n;++x)
        {
	        for (y=0;y<n;++y) printf("%3d",a[x][y]);
	        printf("\n");
          }
           return 0;	
}

【说明】:

这段程序充分利用了C++语言简洁的优势。首先,赋值x=0和y=n-1后马上要把它们作为a数组的下标,因此可以合并完成;tot和a[0][n-1]都要赋值1,也可以合并完成。这样,我们用一条语句完成了多件事情,而且并没有牺牲程序的可读性,这段代码的含义显而易见。
那4条while语句有些难懂,不过十分相似,因此只需介绍其中的第一条:不断向下走,并且填数。我们的原则是:先判断,再移动,而不是走一步以后发现越界了再退回来。这样,我们需要进行“预判”,即是否越界,以及如果继续往下走会不会到达一个已经填过的格子。越界只需判断x+1<n,因为y值并没有修改;下一个格子是(x+1,y),因此只需a[x+1][y]==0,简写成!a[x+1][y](其中!是“逻辑非”运算符)。
细心的读者也许会发现这里的一个“潜在bug”;如果越界,x+1会等于n,a[x+1][y]将访问非法内存!幸运的是,这样的担心是不必要的。&&是短路运算符。如果x+1<n为假,将不会计算!a[x+1][y],也就不会越界了。
至于为什么是++tot而不是tot++,留给读者思考。

 

标签:int,元素,矩阵,二维,数组,include
来源: https://www.cnblogs.com/smghj/p/15988975.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有