5.二维数组

5.复杂数据类型-数组-二维数组


5.1 知识点

基本概念

  • 二维数组是使用两个下标(索引)来确定元素的数组。
  • 两个下标可以理解成行标和列标。
  • 可以用二维数组 int[2,3] 表示,好比两行三列的数据集合。
  • 声明一个二维数组可以理解为连续分配了 行 x 列 个房间。

数组的声明

  • 变量类型[,] 二维数组变量名;

    int[,] arr;
    //声明过后会在后面进行初始化,此时还没分配内存空间。
    
  • 变量类型[,] 二维数组变量名 = new 变量类型[行,列];

    int[,] arr2 = new int[3, 3];
    //分配了3行3列的内存空间,但都还默认为0。
    
  • 变量类型[,] 二维数组变量名 = new 变量类型[行,列]{ {0行内容1, 0行内容2, 0行内容3...}, {1行内容1, 1行内容2, 1行内容3...}, {2行内容1, 2行内容2, 2行内容3...}...};

    int[,] arr3 = new int[3, 3] { { 1, 2, 3 }, 
                                  { 4, 5, 6 }, 
                                  { 7, 8, 9 } };
    //分配了3行3列的内存空间,因为声明了行列数,所以必须要写满三行三列。
    
  • 变量类型[,] 二维数组变量名 = new 变量类型[,]{ {0行内容1, 0行内容2, 0行内容3...}, {1行内容1, 1行内容2, 1行内容3...}, {2行内容1, 2行内容2, 2行内容3...}...};

    int[,] arr4 = new int[,] { { 1, 2, 3 },
                               { 4, 5, 6 },};
    //分配了2行3列的内存空间,因为没有声明行列数,所以几行几列可以根据后面初始化的行列数决定。
    
  • 变量类型[,] 二维数组变量名 = { {0行内容1, 0行内容2, 0行内容3...}, {1行内容1, 1行内容2, 1行内容3...}...};

    int[,] arr5 = { { 1, 2, 3 },
                     { 4, 5, 6 },
                     { 7, 8, 9 } };
    //这种声明方式省略了数组的长度和 new 变量类型[]。
    //后面的内容的行列就决定了数组的行列数。
    //前面的变量类型决定了数组类型。
    

数组的使用

  • int[,] array = new int[,] { { 1, 2, 3 }, { 4, 5, 6 } };

  • 二维数组的长度

    //得到数组有多少行
    Console.WriteLine(array.GetLength(0));
    //得到数组有多少列
    Console.WriteLine(array.GetLength(1));
    
  • 获取二维数组中的元素

    //注意:第一个元素的索引是0,最后一个元素的索引肯定是长度-1
    Console.WriteLine(array[0, 1]);//2
    Console.WriteLine(array[1, 2]);//6
    Console.WriteLine(array[array.GetLength(0)-1, array.GetLength(1-1)]);//6
    //这是输出数组最后一行和最后一列的元素,注意不要越界。
    
  • 修改二维数组中的元素

    array[0, 0] = 99;
    Console.WriteLine(array[0, 0]);//99
    
  • 遍历二维数组

    //套路:两层循环
    for (int i = 0; i < array.GetLength(0); i++)//遍历行
    {
        for (int j = 0; j < array.GetLength(1); j++)//遍历列
        {
            //i 行 0 1
            //j 列 0 1 2
            Console.WriteLine(array[i, j]);
            //0,0  0,1  0,2
            //1,0  1,1  1,2
        }
    }
    
  • 增加数组的元素

    // 数组声明初始化过后,就不能再原有的基础上进行添加。
    //要重新声明比原来数组更多行或列的数组。
    int[,] array2 = new int[3, 3];
    //搬家,用两层循环把新数组前面的值赋值为旧数组的值。
    for (int i = 0; i < array.GetLength(0); i++)
    {
        for (int j = 0; j < array.GetLength(1); j++)
        {
            array2[i, j] = array[i, j];
        }
    }
    //让旧数组指向新数组,就是让旧数组指向了内存中的新地址。
    array = array2;
    //设置新增加的元素的值。
    array[2, 0] = 7;
    array[2, 1] = 8;
    array[2, 2] = 9;
    //把新增加的数组打印出来。
    for (int i = 0; i < array.GetLength(0); i++)
    {
        for (int j = 0; j < array.GetLength(1); j++)
        {
            //i 行 0 1
            //j 列 0 1 2
            Console.WriteLine(array[i, j]);
            //0,0  0,1  0,2
            //1,0  1,1  1,2
        }
    }//99 2 3 4 5 6 7 8 9
    
  • 删除数组的元素

    // 数组声明初始化过后,就不能再原有的基础上进行删除。
    //要重新声明比原来数组更少行或列的数组。
    int[,] array3 = new int[1, 2];
    //搬家,用两层循环把新数组前面的值赋值为旧数组的值。
    for (int i = 0; i < array3.GetLength(0); i++)
    {
        for (int j = 0; j < array3.GetLength(1); j++)
        {
            array3[i, j] = array[i, j];
        }
    }
    //让旧数组指向新数组,就是让旧数组指向了内存中的新地址。
    array = array3;
    //得到删除元素后数组有多少行。
    Console.WriteLine(array3.GetLength(0));//1
    //得到删除元素后数组有多少列。
    Console.WriteLine(array3.GetLength(1));//2
    
  • 查找数组中的元素

    // 如果要在数组中查找一个元素是否等于某个值。
    // 通过遍历的形式去查找。
    //声明要查找的值。
    int a = 2;
    //两层遍历加 if 语句查找数组中的元素。
    for (int i = 0; i < array.GetLength(0); i++)
    {
        for (int j = 0; j < array.GetLength(1); j++)
        {
            //现在 array 是一行二列{99,2}
            if (array[i, j] == a)
            {
                Console.WriteLine("和 a 相等的元素在 {0} 行 {1} 列索引位置", i, j);//和 a 相等的元素在 0 行 1 列索引位置
                break;
            }
        }
    }
    

总结

  • 概念:同一变量类型的行列数据集合。
  • 一定要掌握的内容:声明,遍历,增删查改。
  • 所有的变量类型都可以声明为二维数组。
  • 游戏中一般用来存储矩阵,在控制台小游戏中可以用二维数组来表示地图格子。

5.2 知识点代码

using System;

namespace Lesson03_二维数组
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("二维数组");

            #region 知识点一 基本概念
            //二维数组 是使用两个下标(索引)来确定元素的数组
            //两个下标可以理解成 行标  和 列标
            //比如矩阵
            // 1 2 3
            // 4 5 6
            // 可以用二维数组 int[2,3]表示 
            // 好比 两行 三列的数据集合

            //声明一个二维数组可以理解为连续分配了 行x 列 个房间
            #endregion

            #region 知识点二 二维数组的声明

            //变量类型[,] 二维数组变量名;
            int[,] arr;
            //声明过后 会在后面进行初始化 此时还没分配内存空间


            //变量类型[,] 二维数组变量名 = new 变量类型[行,列];
            int[,] arr2 = new int[3, 3];
            //分配了3行3列的内存空间 但都还默认为0


            //变量类型[,] 二维数组变量名 =new 变量类型[行,列]{ {0行内容1, 0行内容2, 0行内容3...},
            //                                              {1行内容1, 1行内容2, 1行内容3...},
            //                                              {2行内容1, 2行内容2, 2行内容3...}...};
            int[,] arr3 = new int[3, 3] { { 1, 2, 3 }, 
                                          { 4, 5, 6 }, 
                                          { 7, 8, 9 } };
            //分配了3行3列的内存空间 因为声明了行列数 所以必须要写满三行三列


            //变量类型[,] 二维数组变量名 = new 变量类型[,]{ {0行内容1, 0行内容2, 0行内容3...},
            //                                              {1行内容1, 1行内容2, 1行内容3...},
            //                                              {2行内容1, 2行内容2, 2行内容3...}...};
            int[,] arr4 = new int[,] { { 1, 2, 3 },
                                       { 4, 5, 6 },};
            //分配了2行3列的内存空间 因为没有声明行列数 所以几行几列可以根据后面初始化的行列数决定



            //变量类型[,] 二维数组变量名 = { {0行内容1, 0行内容2, 0行内容3...},
            //                           {1行内容1, 1行内容2, 1行内容3...}...};
            int[,] arr5 = { { 1, 2, 3 },
                            { 4, 5, 6 },
                            { 7, 8, 9 } };
            //这种声明方式 省略了数组的长度和new 变量类型[]
            //后面的内容的行列就决定了 数组的行列数
            //前面的变量类型决定了数组类型

            #endregion

            #region 知识点三 二维数组的使用

            int[,] array = new int[,] { { 1, 2, 3 },
                                        { 4, 5, 6 } };


            //1.二维数组的长度

            //得到数组有多少行
            Console.WriteLine(array.GetLength(0));
            //得到数组有多少列
            Console.WriteLine(array.GetLength(1));


            //2.获取二维数组中的元素
            // 注意:第一个元素的索引是0 最后一个元素的索引 肯定是长度-1
            Console.WriteLine(array[0, 1]);//2
            Console.WriteLine(array[1, 2]);//6
            Console.WriteLine(array[array.GetLength(0)-1, array.GetLength(1-1)]);//6
            //这是输出数组最后一行和最后一列的元素 注意不要越界


            //3.修改二维数组中的元素
            array[0, 0] = 99;
            Console.WriteLine(array[0, 0]);//99


            //4.遍历二维数组

            //套路:两层循环
            for (int i = 0; i < array.GetLength(0); i++)//遍历行
            {
                for (int j = 0; j < array.GetLength(1); j++)//遍历列
                {
                    //i 行 0 1
                    //j 列 0 1 2
                    Console.WriteLine(array[i, j]);
                    //0,0  0,1  0,2
                    //1,0  1,1  1,2
                }
            }




            //5.增加数组的元素

            // 数组 声明初始化过后 就不能再原有的基础上进行添加

            //要重新声明比原来数组更多行或列的的数组
            int[,] array2 = new int[3, 3];

            //搬家 用两层循环把新数组前面的值赋值为旧数组的值
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    array2[i, j] = array[i, j];
                }
            }

            //让旧数组指向新数组 就是让旧数组指向了内存中的新地址
            array = array2;
            //设置新增加的元素的值
            array[2, 0] = 7;
            array[2, 1] = 8;
            array[2, 2] = 9;
            
            //把新增加的数组打印出来
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    //i 行 0 1
                    //j 列 0 1 2
                    Console.WriteLine(array[i, j]);
                    //0,0  0,1  0,2
                    //1,0  1,1  1,2
                }
            }//99 2 3 4 5 6 7 8 9




            //6.删除数组的元素
            //留给大家思考 自己去做一次

            // 数组 声明初始化过后 就不能再原有的基础上进行删除

            //要重新声明比原来数组更少行或列的的数组
            int[,] array3 = new int[1, 2];

            //搬家 用两层循环把新数组前面的值赋值为旧数组的值
            for (int i = 0; i < array3.GetLength(0); i++)
            {
                for (int j = 0; j < array3.GetLength(1); j++)
                {
                    array3[i, j] = array[i, j];
                }
            }

            //让旧数组指向新数组 就是让旧数组指向了内存中的新地址
            array = array3;

            //得到删除元素后数组有多少行
            Console.WriteLine(array3.GetLength(0));//1
            //得到删除元素后数组有多少列
            Console.WriteLine(array3.GetLength(1));//2



            //7.查找数组中的元素
            // 如果要在数组中查找一个元素是否等于某个值
            // 通过遍历的形式去查找

            //声明要查找的值
            int a = 2;

            //两层遍历加if语句查找数组中的元素
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    //现在array是一行二列{99,2}
                    if (array[i, j] == a)
                    {
                        Console.WriteLine("和a相等的元素在{0}行{1}列索引位置", i,j);//和a相等的元素在0行1列索引位置
                        break;
                    }
                }
            }

            #endregion

            //总结:
            //1.概念:同一变量类型的 行列数据集合
            //2.一定要掌握的内容:声明,遍历,增删查改
            //3.所有的变量类型都可以声明为 二维数组
            //4.游戏中一般用来存储 矩阵,再控制台小游戏中可以用二维数组 来表示地图格子
        }
    }
}

5.3 练习题

将1到10000赋值给一个二维数组(100行100列)

int[,] array = new int[100, 100];
int index = 1;

for (int i = 0; i < array.GetLength(0); i++)
{
    for (int j = 0; j < array.GetLength(1); j++)
    {
        array[i, j] = index;
        ++index;
        Console.Write(array[i, j] + " ");
    }
    Console.WriteLine();
}

将二维数组(4行4列)的右上半部分置零(元素随机1~100)

array = new int[4, 4];
Random r = new Random();

for (int i = 0; i < array.GetLength(0); i++)
{
    for (int j = 0; j < array.GetLength(1); j++)
    {
        if (i <= 1 && j > 1)
        {
            array[i, j] = 0;
        }
        else
        {
            array[i, j] = r.Next(1, 101);
        }
        Console.Write(array[i, j] + " ");
    }
    Console.WriteLine();
}

求二维数组(3行3列)的对角线元素的和(元素随机1~10)

array = new int[3, 3];
r = new Random();
int sum = 0;

for (int i = 0; i < array.GetLength(0); i++)
{
    for (int j = 0; j < array.GetLength(1); j++)
    {
        array[i, j] = r.Next(1, 11);
        if (i == j || i + j == 2)
        {
            sum += array[i, j];
        }
        Console.Write(array[i, j] + " ");
    }
    Console.WriteLine();
}
Console.WriteLine(sum);

求二维数组(5行5列)中最大元素值及其行列号(元素随机1~500)

array = new int[5, 5];
r = new Random();
int maxI = 0;
int maxJ = 0;

for (int i = 0; i < array.GetLength(0); i++)
{
    for (int j = 0; j < array.GetLength(1); j++)
    {
        array[i, j] = r.Next(1, 501);
        Console.Write(array[i, j] + " ");

        if (array[maxI, maxJ] < array[i, j])
        {
            maxI = i;
            maxJ = j;
        }
    }
    Console.WriteLine();
}

Console.WriteLine("最大值为{0},行{1}列{2}", array[maxI, maxJ], maxI, maxJ);

给一个M*N的二维数组,数组元素的值为0或者1,要求转换数组,将含有1的行和列全部置1

int[,] array = new int[5, 5] { { 0, 0, 0, 0, 0 },
                               { 0, 0, 0, 0, 0 },
                               { 0, 0, 1, 1, 0 },
                               { 0, 0, 0, 0, 0 },
                               { 0, 0, 0, 0, 0 } };
Random r = new Random();

bool[] hang = new bool[5];
bool[] lie = new bool[5];

for (int i = 0; i < array.GetLength(0); i++)
{
    for (int j = 0; j < array.GetLength(1); j++)
    {
        if (array[i, j] == 1)
        {
            hang[i] = true;
            lie[j] = true;
        }
        Console.Write(array[i, j] + " ");
    }
    Console.WriteLine();
}

Console.WriteLine("**************");

for (int i = 0; i < array.GetLength(0); i++)
{
    for (int j = 0; j < array.GetLength(1); j++)
    {
        if (hang[i] || lie[j])
        {
            array[i, j] = 1;
        }
        Console.Write(array[i, j] + " ");
    }
    Console.WriteLine();
}

5.4 练习题代码

using System;

namespace Lesson03_练习题
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("二维数组练习题");

            #region 练习题一
            //将1到10000赋值给一个二维数组(100行100列)
            int[,] array = new int[100, 100];
            int index = 1;
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    array[i, j] = index;
                    ++index;
                    Console.Write(array[i, j] + " ");
                }
                Console.WriteLine();
            }
            #endregion

            #region 练习题二
            //将二维数组(4行4列)的右上半部分置零(元素随机1~100)
            array = new int[4, 4];
            Random r = new Random();
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    if (i <= 1 && j > 1)
                    {
                        array[i, j] = 0;
                    }
                    else
                    {
                        array[i, j] = r.Next(1, 101);
                    }
                    Console.Write(array[i, j] + " ");
                }
                Console.WriteLine();
            }
            #endregion

            #region 练习题三
            //求二维数组(3行3列)的对角线元素的和(元素随机1~10)
            array = new int[3, 3];
            r = new Random();
            int sum = 0;
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    array[i, j] = r.Next(1, 11);
                    //对角线 元素 满足的条件
                    if (i == j || i + j == 2)
                    {
                        sum += array[i, j];
                    }
                    Console.Write(array[i, j] + " ");
                }
                Console.WriteLine();
            }
            Console.WriteLine(sum);
            #endregion

            #region 练习题四
            //求二维数组(5行5列)中最大元素值及其行列号(元素随机1~500)
            array = new int[5, 5];
            r = new Random();
            //就是记录 最大值的 行列号
            int maxI = 0;
            int maxJ = 0;
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    array[i, j] = r.Next(1, 501);
                    Console.Write(array[i, j] + " ");
                    //找最大值
                    if (array[maxI, maxJ] < array[i, j])
                    {
                        maxI = i;
                        maxJ = j;
                    }
                }
                Console.WriteLine();
            }

            Console.WriteLine("最大值为{0},行{1}列{2}", array[maxI, maxJ], maxI, maxJ);
            #endregion

            #region 练习题五
            //给一个M*N的二维数组,数组元素的值为0或者1,
            //要求转换数组,将含有1的行和列全部置1

            array = new int[5, 5] { { 0,0,0,0,0},
                                    { 0,0,0,0,0},
                                    { 0,0,1,1,0},
                                    { 0,0,0,0,0},
                                    { 0,0,0,0,0}};
            r = new Random();

            //声明行列的标记数组 只要某一行或列有1 就改变标记为true
            bool[] hang = new bool[5];
            bool[] lie = new bool[5];

            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    //array[i, j] = r.Next(0, 2);
                    if( array[i,j] == 1 )
                    {
                        //记录了 当前 行列 是否要变1的标识 
                        //要变一 就置true
                        hang[i] = true;
                        lie[j] = true;
                    }
                    Console.Write(array[i, j] + " ");
                }
                Console.WriteLine();
            }

            Console.WriteLine("**************");

            //两层循环判断每个元素的行或列的标识为不为true 为true的话改为1
            for (int i = 0; i < array.GetLength(0); i++)
            {
                for (int j = 0; j < array.GetLength(1); j++)
                {
                    //满足行和列的标识 是ture 就变一
                    if( hang[i] || lie[j] )
                    {
                        array[i, j] = 1;
                    }
                    Console.Write(array[i, j] + " ");
                }
                Console.WriteLine();
            }

            #endregion
        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏