我们知道有很多数学软件,如MatLab是面向矩阵的,而开源语言R是面向向量的,SQL是面向关系系的、APL(Array processing language)是一种一种多用途、第三代(3GL)编程语言,在向量、矩阵等各种秩的数组处理上非常简单。SPSS,SAS等都需要大量的集合运算。

德清ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为创新互联的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!
本文试图从C#本身的特性出发,模拟C#面向集合的方法。
更期望C#面向集合能向MatLab, APL,R那样直接处理集合运算,进入科学和工程计算领域,为以后的并行计算奠定基础。
有一列观测值,用List存储,我们现在需要求出每一个观测值的正弦Sin值。
用C#面向过程的语法表示如下:
- List list2;
 - for (int i = 0; i < list2.Count; i++)
 - list2[i] = Math.Sin(list2[i]);
 
求Sin值,是一个繁琐而又重复的问题。我们希望Math.Sin(Collection c),在不改变已有代码(不扩展Math.Sin)的情况下,自动处理集合,就像在MatLab里面。
C#是面向过程的,而Matlab是面向矩阵的,SQL是面向关系代数的。关系代数和矩阵,都可以看作集合的特例。(LINQ部分加入了面向集合的特性)
面向过程,需要程序员书写算法的每一个过程和细节,指明执行路径,这主要表现在循环语句的使用上(包括for, foreach, while…)。
面向过程给了程序员最充分的自由和最大的灵活,但其固有的“底层”,导致了开发效率的底下,同时不利于并行计算和系统优化。而在数学中,大部分计算都是基于矩阵(集合),例如图形图像处理,概率论,数理统计,优化控制等等。 所以C#难以胜任运算集中和知识处理,人工智能设计。
由于C#实在是太优美,是目前最艺术的语言,利用C#现有特性,我们可以简单的模拟前面提出的问题
- public static List Apply(Converter f, List l)
 - {
 - List list2 = new List(l);
 - for (int i = 0; i < list2.Count; i++)
 - list2[i] = Math.Sin(list2[i]);
 - for (int i = 0; i < l.Count; i++)
 - {
 - list2[i] = f(l[i]);
 - }
 - return list2;
 - }
 
这样,我们可以在Apply来处理一些关于集合处理的问题。
下面在给出一个处理矩阵的例子:
- public static Matrix Apply(Converter f, Matrix m)
 - {
 - Matrix m2 = new Matrix(m);
 - for (int i = 0; i < m.Row; i++)
 - for (int j = 0; j < m.Col; j++)
 - m2[i, j] = f(m2[i, j]);
 - return m2;
 - }
 
使用这个Apply,可以处理矩阵集合相关的计算。
矩阵定义如下:
- public class Matrix
 - {
 - public double[,] data;
 - public Matrix(int row, int col)
 - {
 - data = new double[row, col];
 - }
 - //复制构造函数
 - public Matrix(Matrix m)
 - {
 - data = (double[,])m.data.Clone();
 - }
 - public int Col
 - {
 - get
 - {
 - return data.GetLength(1);
 - }
 - }
 - // 行数
 - public int Row
 - {
 - get
 - {
 - return data.GetLength(0);
 - }
 - }
 - //重载索引
 - //存取数据成员
 - public virtual double this[int row, int col]
 - {
 - get
 - {
 - return data[row, col];
 - }
 - set
 - {
 - data[row, col] = value;
 - }
 - }
 - //维数
 - public int Dimension
 - {
 - get { return 2; }
 - }
 - public string ToString(int prec)
 - {
 - StringBuilder sb = new StringBuilder();
 - string format = "{0:F" + prec.ToString() + "} ";
 - for (int i = 0; i < Row; i++)
 - {
 - for (int j = 0; j < Col - 1; j++)
 - {
 - sb.Append(string.Format(format, data[i, j]));
 - }
 - sb.Append(data[i, Col - 1]);
 - sb.Append(""n");
 - }
 - return sb.ToString();
 - }
 - }
 
再看下面复数的例子:
- public static List Apply(Converter< Complex,double> f, List l)
 - {
 - List l2 = new List(l.Count);
 - for (int i = 0; i < l.Count; i++)
 - l2.Add(f(l[i]));
 - return l2;
 - }
 
使用这个Apply,可以处理复数集合相关的许多计算。
复数类的定义如下:
- Code
 - public class Complex:ICloneable
 - {
 - private double real;
 - /**////
 - /// 复数的实部
 - ///
 - public double Real
 - {
 - get { return real; }
 - set { real = value; }
 - }
 - private double image;
 - /**////
 - /// 复数的虚部
 - ///
 - public double Image
 - {
 - get { return image; }
 - set { image = value; }
 - }
 - /**////
 - /// 默认构造函数
 - ///
 - public Complex()
 - : this(0, 0)
 - {
 - }
 - /**////
 - /// 只有实部的构造函数
 - ///
 - /// 实部
 - public Complex(double real)
 - : this(real, 0) { }
 - /**////
 - /// 由实部和虚部构造
 - ///
 - /// 实部
 - /// 虚部
 - public Complex(double r, double i)
 - {
 - rreal = r;
 - iimage = i;
 - }
 - /**////重载加法
 - public static Complex operator +(Complex c1, Complex c2)
 - {
 - return new Complex(c1.real + c2.real, c1.image + c2.image);
 - }
 - /**////重载减法
 - public static Complex operator -(Complex c1, Complex c2)
 - {
 - return new Complex(c1.real - c2.real, c1.image - c2.image);
 - }
 - /**////重载乘法
 - public static Complex operator *(Complex c1, Complex c2)
 - {
 - return new Complex(c1.real * c2.real - c1.image * c2.image, c1.image * c2.real + c1.real * c2.image);
 - }
 - /**////
 - /// 求复数的模
 - ///
 - /// 模
 - public double Modul
 - {
 - get
 - {
 - return Math.Sqrt(real * real + image * image);
 - }
 - }
 - public static double Sin(Complex c)
 - {
 - return c.image / c.Modul;
 - }
 - /**////
 - /// 重载ToString方法
 - ///
 - /// 打印字符串
 - public override string ToString()
 - {
 - if (Real == 0 && Image == 0)
 - {
 - return string.Format("{0}", 0);
 - }
 - if (Real == 0 && (Image != 1 && Image != -1))
 - {
 - return string.Format("{0} i", Image);
 - }
 - if (Image == 0)
 - {
 - return string.Format("{0}", Real);
 - }
 - if (Image == 1)
 - {
 - return string.Format("i");
 - }
 - if (Image == -1)
 - {
 - return string.Format("- i");
 - }
 - if (Image < 0)
 - {
 - return string.Format("{0} - {1} i", Real, -Image);
 - }
 - return string.Format("{0} + {1} i", Real, Image);
 - }
 - ICloneable 成员#region ICloneable 成员
 - public object Clone()
 - {
 - Complex c = new Complex(real, image);
 - return c;
 - }
 - #endregion
 - }
 
从前面三个例子,我们可以看出,C#面向集合有多种表示方式,有.net框架中的List,也有自定义的Matrix,同时集合的元素也是多种数据类型,有系统中的值类型,也有自定义的复数Complex类型。
当然这种算法过于勉强,显然不是我们所需要的。
我们需要的是一个在不更改现有语言的情况下,不扩充Math.Sin函数(试着想想有多少个类似的函数,Cos, Tan, 我们自己定义的各种函数)。系统自动处理集合。也就是说,对于函数 public delegate TOutput Converter (TInput input);public T1 Func (T2 e); Func是Converter的实例。只要Func能够处理原子类型,那么就能处理自动所有的原子类型构成的任意集合,而不需要程序员去写多余的代码。
                当前标题:讨论一下C#面向集合的扩展
                
                转载注明:http://www.csdahua.cn/qtweb/news30/173180.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网