用C#实现矩阵

在数学中,矩阵(Matrix)是一个按照长方阵列排列的复数或实数的集合

对于一个长方形可以使用一个二维数组来实现。
于是

    public class Matrix//矩阵类
    {
        public int[,] x;//定义一个矩阵字段
    }

矩阵是需要大小的,如 m*n 的矩阵,就是 m 行 n 列。

Matrix x = new Matrix();//对矩阵类实例化

这时我们完成了一个矩阵类,并对其实例化。
但是现在缺少内容,大小也没有确认。

    public class CreatMatrix//为矩阵随机赋值
    {
        public static int[,] creaM (int m,int n)
        {
            int[,] x = new int[m, n];//初始化矩阵
            Random r = new Random();//创建随机类实例
            for (int i = 0;i < m; i++)//对二维矩阵所有点遍历
            {
                for (int j = 0; j <n; j++)
                {
                    //x[i, j] = r.Next(0, 10);//对二维矩阵每个点赋值
                    x[i, j] = i + j;
                }
            }
            return x;
        }
    }

实现一个创建矩阵类,创建一个静态方法,传入矩阵的长和宽随机为矩阵赋值。
随机方法通过对 Random() 实例化完成。

在完成矩阵定义,创建,之后需要获取矩阵。
对于直接输出矩阵会得到 System.Int32[,]

WriteLine(矩阵);

要注意,数组是引用类型,因此会返回它的引用,而不是内容。
对于int数组的内容是值类型的,要获取全部元素需要对其遍历

    public class ShowMatrix//暂时二维数组
    {
        public static void showM(int[,] x)//传入数组
        {
            //int k = x.Rank;//获取数组维度
            int m = x.GetLength(0);//获取行数
            int n = x.GetLength(1);//获取行列
            //GetLength() 获取指定维度长度,而对于多维数组的维度如[5,7,9]
            //5是一维的长度,7是二维的长度,9是三维的长度
            for (int i = 0; i < m; i++)//每一行
            {                           
                for (int j = 0; j < n; j++)//每一列
                {                  
                    Write("{0} ",x[i,j]);                   // 输出数组中的元素
                }
                WriteLine();                                //换行
            }
        }
    }

这里就实现了传入一个 二维数组,获取其行和列的长度
GetLength(0)是行的长度。
GetLength(1)是列的长度.
其中0和1表示的是其维度。

完整代码如下

using System;
using static System.Console;

namespace ConsoleApp
{
    public class Matrix//矩阵类
    {
        public int[,] x;//定义一个矩阵字段
    }
    public class CreatMatrix//为矩阵随机赋值
    {
        public static int[,] creaM (int m,int n)
        {
            int[,] x = new int[m, n];//初始化矩阵
            Random r = new Random();//创建随机类实例
            for (int i = 0;i < m; i++)//对二维矩阵所有点遍历
            {
                for (int j = 0; j <n; j++)
                {
                    //x[i, j] = r.Next(0, 10);//对二维矩阵每个点赋值
                    x[i, j] = r.Next(0,10);
                }
            }
            return x;
        }
    }
    public class ShowMatrix//暂时二维数组
    {
        public static void showM(int[,] x)//传入数组
        {
            //int k = x.Rank;//获取数组维度
            int m = x.GetLength(0);//获取行数
            int n = x.GetLength(1);//获取行列
            //GetLength() 获取指定维度长度,而对于多维数组的维度如[5,7,9]
            //5是一维的长度,7是二维的长度,9是三维的长度
            for (int i = 0; i < m; i++)//每一行
            {                           
                for (int j = 0; j < n; j++)//每一列
                {                  
                    Write("{0} ",x[i,j]);                   // 输出数组中的元素
                }
                WriteLine();                                //换行
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Matrix x1 = new Matrix();//对矩阵类实例化
            x1.x = CreatMatrix.creaM(7, 10);//创建矩阵并复制
            WriteLine(x1.x);
            ShowMatrix.showM(x1.x);//输出矩阵
            ReadKey();
        }
    }
}

对于矩阵应该实现加法,乘法运算。
这就涉及到运算符重载。

要进行矩阵运算就不能只有一个矩阵,因此我创建多个矩阵

    class Program
    {
        static void Main(string[] args)
        {
            Matrix x1 = new Matrix();
            Matrix x2 = new Matrix();
            Matrix x3 = new Matrix();
            x1.x = CreatMatrix.creaM(7, 10);
            x2.x = CreatMatrix.creaM(7, 10);
            x3.x = CreatMatrix.creaM(7, 10);
            ShowMatrix.showM(x1.x);
            WriteLine("----------------");
            ShowMatrix.showM(x2.x);
            WriteLine("----------------");
            ShowMatrix.showM(x3.x);
            WriteLine("----------------");
            ReadKey();
        }
    }

这时出现了问题,我创建的三个矩阵完全相同。


image.png

对于矩阵中的元素赋值我采用随机数的方法,回到矩阵赋值类查看原因

    public class CreatMatrix//为矩阵随机赋值
    {
        public static int[,] creaM (int m,int n)
        {
            int[,] x = new int[m, n];//初始化矩阵
            Random r = new Random();//创建随机类实例
            for (int i = 0;i < m; i++)//对二维矩阵所有点遍历
            {
                for (int j = 0; j <n; j++)
                {
                    //x[i, j] = r.Next(0, 10);//对二维矩阵每个点赋值
                    x[i, j] = i + j;
                }
            }
            return x;
        }
    }

发现我写的赋值矩阵方法是静态的,静态方法对每个实例都是相同的(应该是这样说的吧)。
但是我将其改写为实例方法后发现还是不行,我由为其创建多个实例对象结果还是一样。(别试了,跟这些没关系)
于是开始寻找别的原因,众所周知,计算机的随机数都是伪随机,通过一些特点的算法使用不同的参数得到不同的值,参数作为种子如果被获悉就可以推断出后续的结果。因此计算机的随机数都是伪随机。
看一下编译器解析


image.png

发现C#的随机数生成是默认依靠时间。
那么就存在一种可能,是拆箱运行太快,并且对时间精度处理不细致。对于使用的时间精度没有考证。
因此我引入

using System.Threading;

然后休眠500毫秒,也就是5秒

Thread.Sleep(500);

此时的赋值类

    public class CreatMatrix//为矩阵随机赋值
    {
        public int[,] creaM (int m,int n)
        {
            int[,] x = new int[m, n];//初始化矩阵
            Random r = new Random();//创建随机类实例
            for (int i = 0;i < m; i++)//对二维矩阵所有点遍历
            {
                for (int j = 0; j <n; j++)
                {
                    //x[i, j] = r.Next(0, 10);//对二维矩阵每个点赋值
                    x[i, j] = r.Next(0,10);
                }
            }
            return x;
        }
    }

此时的运行程序

    class Program
    {
        static void Main(string[] args)
        {
            Matrix x1 = new Matrix();
            Matrix x2 = new Matrix();
            Matrix x3 = new Matrix();
            CreatMatrix c = new CreatMatrix();
            x1.x = c.creaM(7, 10);
            Thread.Sleep(500);
            x2.x = c.creaM(7, 10);
            Thread.Sleep(500);
            x3.x = c.creaM(7, 10);
            ShowMatrix.showM(x1.x);
            WriteLine("----------------");
            ShowMatrix.showM(x2.x);
            WriteLine("----------------");
            ShowMatrix.showM(x3.x);
            WriteLine("----------------");
            ReadKey();
        }
    }

结果


image.png

成功了。
但是500毫秒的休眠时间对程序运行速度产生影响,因此尝试缩小范围,在我的计算机行10毫秒左右总会出现3个矩阵两个相等,但也会出现完全不相等的情况,5毫秒左右几乎完全相等,但也存在有一个不同于其他两个,在20毫秒左右几乎不会出现相等。

然后在测试一下是否和静态方法有关。
赋值类

    public class CreatMatrix//为矩阵随机赋值
    {
        public static int[,] creaM (int m,int n)
        {
            int[,] x = new int[m, n];//初始化矩阵
            Random r = new Random();//创建随机类实例
            for (int i = 0;i < m; i++)//对二维矩阵所有点遍历
            {
                for (int j = 0; j <n; j++)
                {
                    //x[i, j] = r.Next(0, 10);//对二维矩阵每个点赋值
                    x[i, j] = r.Next(0,10);
                }
            }
            return x;
        }
    }

运行

    class Program
    {
        static void Main(string[] args)
        {
            Matrix x1 = new Matrix();
            Matrix x2 = new Matrix();
            Matrix x3 = new Matrix();
            x1.x = CreatMatrix.creaM(7, 10);
            Thread.Sleep(500);
            x2.x = CreatMatrix.creaM(7, 10);
            Thread.Sleep(500);
            x3.x = CreatMatrix.creaM(7, 10);
            ShowMatrix.showM(x1.x);
            WriteLine("----------------");
            ShowMatrix.showM(x2.x);
            WriteLine("----------------");
            ShowMatrix.showM(x3.x);
            WriteLine("----------------");
            ReadKey();
        }
    }

结果


image.png

很尴尬的发现和静态方法无关,看来我是误会什么了。还要学习啊。

静态方法属于类所有,为各个类的实例所公用。
然而我这里写的静态方法就是一个方法,被直接调用,因此每次的结果是不同的。

再保留一下当前代码

using System;
using static System.Console;
using System.Threading;

namespace ConsoleApp
{
    public class Matrix//矩阵类
    {
        public int[,] x;//定义一个矩阵字段
    }
    public class CreatMatrix//为矩阵随机赋值
    {
        public static int[,] creaM (int m,int n)
        {
            int[,] x = new int[m, n];//初始化矩阵
            Random r = new Random();//创建随机类实例
            for (int i = 0;i < m; i++)//对二维矩阵所有点遍历
            {
                for (int j = 0; j <n; j++)
                {
                    //x[i, j] = r.Next(0, 10);//对二维矩阵每个点赋值
                    x[i, j] = r.Next(0,10);
                }
            }
            return x;
        }
    }
    public class ShowMatrix//暂时二维数组
    {
        public static void showM(int[,] x)//传入数组
        {
            //int k = x.Rank;//获取数组维度
            int m = x.GetLength(0);//获取行数
            int n = x.GetLength(1);//获取行列
            //GetLength() 获取指定维度长度,而对于多维数组的维度如[5,7,9]
            //5是一维的长度,7是二维的长度,9是三维的长度
            for (int i = 0; i < m; i++)//每一行
            {                           
                for (int j = 0; j < n; j++)//每一列
                {                  
                    Write("{0} ",x[i,j]);                   // 输出数组中的元素
                }
                WriteLine();                                //换行
            }
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Matrix x1 = new Matrix();
            Matrix x2 = new Matrix();
            Matrix x3 = new Matrix();
            x1.x = CreatMatrix.creaM(7, 10);
            Thread.Sleep(500);
            x2.x = CreatMatrix.creaM(7, 10);
            Thread.Sleep(500);
            x3.x = CreatMatrix.creaM(7, 10);
            ShowMatrix.showM(x1.x);
            WriteLine("----------------");
            ShowMatrix.showM(x2.x);
            WriteLine("----------------");
            ShowMatrix.showM(x3.x);
            WriteLine("----------------");
            ReadKey();
        }
    }
}

对于随机数生成如果一直使用休眠的方法会影响程序的运行效率,应该采用其他方法,明天再探讨。还有运算符重载明天再说吧。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,324评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,356评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,328评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,147评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,160评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,115评论 1 296
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,025评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,867评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,307评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,528评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,688评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,409评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,001评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,657评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,811评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,685评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,573评论 2 353