C#DataTable一些使用方法

c++调用c#写的DLL;

写在前方

一切项目都托管在了 Github
上:

搜寻更为方便的本子见:https://alg4.ikesnowy.com

那风流洒脱节内容可能会用到的库文件有 Merge,相仿在 Github 上得以找到。

善用 Ctrl + F 查找难点。

  1,使用DataTable必定要引用System.Data.

此小说演示了树立c#的dll;

习题&题解

  2,定义叁个DataTable

c++创立工程,引进dll;

2.2.1

DataTable dt=new DataTable();

无法清除的主题材料:

题目

依照本书开端所示轨迹的格式给出原地合併列排在一条线序的肤浅 merge()
方法是何许将数组 A E Q S U Y E I N O S T 排序的。

 3,为DataTable创建列

钦定dll的路径,在代码里面一向写 #using “xxx.dll” 一定要在使用路线
#using “../bin/debug/xxx.dll”

解答

图片 1

 

//1.创建空列
DataColumn dc = new DataColumn();
dt.Columns.Add(dc);
//2.创建带列名和类型名的列
dt.Columns.Add("column0", typeof(String));
//3.通过列架构添加列
DataColumn dc = new DataColumn("column1", typeof(String));
dt.Columns.Add(dc);

 

2.2.2

 4,为DataTable创建行

1-建立c#的dll,过程略;

题目

依照算法 2.4 所示轨迹的格式给来自顶向下的归总列排在一条线序是怎么样将数组 E A S Y Q
U E S T I O N 排序的。

//1.创建空行
DataRow dr = dt.NewRow();
dt.Rows.Add(dr);
//2.创建空行
dt.Rows.Add();
//3.通过行框架创建并赋值
dt.Rows.Add("小明",18);//Add里面参数的数据顺序要和dt中的列的顺序对应 
//4.通过复制dt2表的某一行来创建
dt.Rows.Add(dt2.Rows[i].ItemArray);

图片 2

解答

图片 3

 

 5,DataTable的取值和赋值

 

2.2.3

//新建行的赋值
DataRow dr = dt.NewRow();
dr[0] = "小明";//通过索引赋值
dr["column1"] = DateTime.Now; //通过名称赋值
//对表已有行进行赋值
dt.Rows[0][0] = "小明"; //通过索引赋值
dt.Rows[0]["column1"] = DateTime.Now;//通过名称赋值
//取值
string name=dt.Rows[0][0].ToString();
string time=dt.Rows[0]["column1"].ToString();

2.校正出口路线输出为 ../bin/debug; ../bin/release 方便c++能够一定找到

题目

用自底向上的联合排序解答练习 2.2.2

 6,DataTable的筛选行和删除行

图片 4

解答

图片 5

 

//select用法
//筛选姓名列值中有"小"的行的集合(模糊查询),第二句可添加按年龄降序排序
DataRow[] dr = dt.Select("姓名 like '小%'");
DataRow[] drs = dt.Select("姓名 like '小%'", "年龄 DESC");

 

2.2.4

//Compute用法

3.在建设方案增添C++工程,进程略

题目

是还是不是当且仅当多个输入的子数组都稳步时原地合并的抽象方法本事获得正确的结果?
表明您的下结论,恐怕给出一个反例。

   Object result = dt.Compute(“sum(成绩)”, “年龄>16 and 姓名 like
‘小*'”);

 

解答

科学,必须求多少个子数组都稳步时合并技艺收获不错结果。
如若说数组不平稳的话,那么最后不能不获取四个数组的交集。
集结后的数组中,归于原有数组的成分的对峙顺序不会被改进。
譬喻子数组 1 3 1 和 2 8 5 原地归总。
结果是 1 2 3 1 8 5,当中 1 3 1 和 2 8 5 的争执顺序不改变。

 

 //result为总计出的结果,compute函数的率先个参数通常为聚合函数,后叁个参数为挑选规范

4.新加上的C++工程,引用DLL,同一时间引进名字空间;

2.2.5

 

  •   援用库使用 #using “xxx.dll” 这里需求制定dll的绝对路径
  • #pragma managed;  // 告诉编写翻译器,将动用托管代码

  • using namespace CsDll002;  // 引进名字空间

题目

当输入数组的大大小小 N=39
时,给来自顶向下和自底向上的会集排序中各次归总子数组的分寸及各种。

//Find用法

 

解答

老是合并子数组的高低和顺序如下:

自顶向下

2, 3, 2, 5, 2, 3, 2, 5, 10, 2, 3, 2, 5, 2, 3, 2, 5, 10, 20, 2, 3, 2, 5,
2, 3, 2, 5, 10, 2, 3, 2, 5, 2, 2, 4, 9, 19, 39

自底向上

2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4,
4, 4, 4, 4, 3, 8, 8, 8, 8, 7, 16, 16, 32, 39

 

dt.PrimaryKey = new DataColumn[] { dt.Columns[“学号”] };

图片 6

2.2.6

 DataRow dr1 = dt.Rows.Find(“004”);

5.利用类库

题目

编制二个程序来测算自顶向下和自底向上的汇合排序访问数组的纯粹次数。
应用这几个顺序将 N=1 至 512 的结果绘成曲线图,并将其和上限 6NlgN 相比较。

//Find用法供给datatable有主键,是豆蔻年华种按主键搜寻意气风发行数据的办法

 尖号表示托管;这里演示了再次来到值使用引用,和C++调用援用同样,无需钦赐特殊字符;

解答

图片 7

灰白是上限,蓝点是自顶向下,红点是自底向上。
出于三种排序访问数组的次数是平等的,因而蓝点和红点重合。

 

与C#区别,如果c# 写的函数是 int  add(int a, int b, ref int resut) 
调用时须要 add(1, 2, ref result);这里C++没有这几个语法供给。

代码

付出绘图部分的代码:

using System;
using System.Windows.Forms;
using System.Drawing;
using Merge;

namespace _2._2._6
{
    /*
     * 2.2.6
     * 
     * 编写一个程序来计算自顶向下和自底向上的归并排序访问数组的准确次数。
     * 使用这个程序将 N=1 至 512 的结果绘成曲线图,
     * 并将其和上限 6NlgN 相比较。
     * 
     */
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Compute();
            Application.Run(new Form1());
        }

        static void Compute()
        {
            MergeSort mergeSort = new MergeSort();
            MergeSortBU mergeSortBU = new MergeSortBU();
            int[] mergeResult = new int[10];
            int[] mergeResultBU = new int[10];
            int[] upperBound = new int[10];

            // 进行计算
            int dataSize = 1;
            for (int i = 0; i < 10; i++)
            {
                int[] dataMerge = SortCompare.GetRandomArrayInt(dataSize);
                int[] dataMergeBU = new int[dataSize];
                dataMerge.CopyTo(dataMergeBU, 0);

                mergeSort.ClearArrayVisitCount();
                mergeSortBU.ClearArrayVisitCount();
                mergeSort.Sort(dataMerge);
                mergeSortBU.Sort(dataMergeBU);

                mergeResult[i] = mergeSort.GetArrayVisitCount();
                mergeResultBU[i] = mergeSortBU.GetArrayVisitCount();
                upperBound[i] = (int)(6 * dataSize * Math.Log(dataSize, 2));

                dataSize *= 2;
            }

            // 绘图
            Form2 plot = new Form2();
            plot.Show();
            Graphics graphics = plot.CreateGraphics();

            // 获得绘图区矩形。
            RectangleF rect = plot.ClientRectangle;
            float unitX = rect.Width / 10;
            float unitY = rect.Width / 10;

            // 添加 10% 边距作为文字区域。
            RectangleF center = new RectangleF
                (rect.X + unitX, rect.Y + unitY,
                rect.Width - 2 * unitX, rect.Height - 2 * unitY);

            // 绘制坐标系。
            graphics.DrawLine(Pens.Black, center.Left, center.Top, center.Left, center.Bottom);
            graphics.DrawLine(Pens.Black, center.Left, center.Bottom, center.Right, center.Bottom);
            graphics.DrawString("28000", plot.Font, Brushes.Black, rect.Location);
            graphics.DrawString("1024", plot.Font, Brushes.Black, center.Right, center.Bottom);
            graphics.DrawString("0", plot.Font, Brushes.Black, rect.Left, center.Bottom);

            // 初始化点。
            PointF[] grayPoints = new PointF[10]; // 上限
            PointF[] redPoints = new PointF[10];  // 自顶向下
            PointF[] bluePoints = new PointF[10]; // 自底向上
            unitX = center.Width / 11.0f;
            unitY = center.Height / 28000.0f;

            for (int i = 0; i < 10; i++)
            {
                grayPoints[i] = new PointF(center.Left + unitX * (i + 1), center.Bottom - (upperBound[i] * unitY) - 10);
                redPoints[i] = new PointF(center.Left + unitX * (i + 1), center.Bottom - (mergeResult[i] * unitY) - 10);
                bluePoints[i] = new PointF(center.Left + unitX * (i + 1), center.Bottom - (mergeResultBU[i] * unitY) - 10);
            }

            // 绘制点。
            for (int i = 0; i < 10; i++)
            {
                graphics.FillEllipse(Brushes.Gray, new RectangleF(grayPoints[i], new SizeF(10, 10)));
                graphics.FillEllipse(Brushes.Red, new RectangleF(redPoints[i], new SizeF(10, 10)));
                graphics.FillEllipse(Brushes.Blue, new RectangleF(bluePoints[i], new Size(10, 10)));
            }

            graphics.Dispose();
        }
    }
}

 

 

 

2.2.7

 

题目

证实归总排序的可比次数是干燥依次增加的(即对于 N>0,C(N+1)>C(N)卡塔 尔(阿拉伯语:قطر‎。

//删除行

解答

据书上说书本给出的命题 G 和命题 H(中文版 P173/176,塞尔维亚语版 P275/279卡塔尔国,
正如次数的下限 C(N) = 51% * NlgN
N 和 lgN 都以干燥依次增加且高于零的(N>1),由此 C(N) 也是没味依次增加的

 

//使用DataTable.Rows.Remove(DataRow)方法

2.2.8

dt.Rows.Remove(dt.Rows[0]);

题目

假设将算法 2.4 校勘为:
只要 a[mid] <= a[mid+1] 就不调用 merge() 方法,
请表达用合併列排在一条线序处理多个意气风发度平稳的数组所需的相比较次数是线性等第的。

//使用DataTable.Rows.RemoveAt(index)方法

解答

纠正后的算法对已经稳步的意况做了优化
数组对半切分并排序后,
如果 a[mid] < a[mid +
1](左半部分的末段叁个要素小于右半部分的率先个要素卡塔 尔(英语:State of Qatar)
那正是说大家得以直接统生机勃勃数组,不供给再做多余的操作

今昔的输入是三个已经排序的数组
算法唯生龙活虎的相比较发生在认清 a[mid] < a[mid + 1] 那几个规格时
假如数组有 N 个要素
正如次数知足 T(N) = 2 * T(N / 2) + 1, T(1) = 0
倒车为非递归格局即为:T(N) = cN / 2 + N – 1
里头 c 为随便正整数

 

dt.Rows.RemoveAt(0);

2.2.9

//使用DataRow.Delete()方法

题目

在库函数中应用 aux[] 那样的静态数组时不妥贴的,
因为或者会有三个程序同有的时候间选用那么些类。
达成三个毫不静态数组的 Merge 类,
但也并不是将 aux[] 变为 merge() 的一些变量(请见本书的答问部分卡塔 尔(英语:State of Qatar)。
提醒:能够将帮扶数组作为参数字传送递给递归的 sort() 方法。

dt.Row[0].Delete();

解答

合法给出的相会排序完成中在 Sort 方法里初阶化了 aux 数组。
源码见:

C#兑现和合法的落实足够附近,

率先定义只接纳二个参数的公开 Sort 方法,在此个方法里面初阶化 aux
数组。

/// <summary>
/// 利用归并排序将数组按升序排序。
/// </summary>
/// <typeparam name="T">数组元素类型。</typeparam>
/// <param name="a">待排序的数组。</param>
public override void Sort<T>(T[] a)
{
    T[] aux = new T[a.Length];
    Sort(a, aux, 0, a.Length - 1);
}

然后创设三个私有的递归 Sort 方法坚实际的排序操作。

/// <summary>
/// 自顶向下地对数组指定范围内进行归并排序,需要辅助数组。
/// </summary>
/// <typeparam name="T">需要排序的元素类型。</typeparam>
/// <param name="a">原数组。</param>
/// <param name="aux">辅助数组。</param>
/// <param name="lo">排序范围起点。</param>
/// <param name="hi">排序范围终点。</param>
private void Sort<T>(T[] a, T[] aux, int lo, int hi) where T : IComparable<T>
{
    if (hi <= lo)
        return;
    int mid = lo + (hi - lo) / 2;
    Sort(a, aux, lo, mid);
    Sort(a, aux, mid + 1, hi);
    Merge(a, aux, lo, mid, hi);
}

dt.AcceptChanges();

代码
using System;

namespace Merge
{
    /// <summary>
    /// 归并排序类。
    /// </summary>
    public class MergeSort : BaseSort
    {
        /// <summary>
        /// 默认构造函数。
        /// </summary>
        public MergeSort() { }

        /// <summary>
        /// 利用归并排序将数组按升序排序。
        /// </summary>
        /// <typeparam name="T">数组元素类型。</typeparam>
        /// <param name="a">待排序的数组。</param>
        public override void Sort<T>(T[] a)
        {
            T[] aux = new T[a.Length];
            Sort(a, aux, 0, a.Length - 1);
        }

        /// <summary>
        /// 自顶向下地对数组指定范围内进行归并排序,需要辅助数组。
        /// </summary>
        /// <typeparam name="T">需要排序的元素类型。</typeparam>
        /// <param name="a">原数组。</param>
        /// <param name="aux">辅助数组。</param>
        /// <param name="lo">排序范围起点。</param>
        /// <param name="hi">排序范围终点。</param>
        private void Sort<T>(T[] a, T[] aux, int lo, int hi) where T : IComparable<T>
        {
            if (hi <= lo)
                return;
            int mid = lo + (hi - lo) / 2;
            Sort(a, aux, lo, mid);
            Sort(a, aux, mid + 1, hi);
            Merge(a, aux, lo, mid, hi);
        }

        /// <summary>
        /// 将指定范围内的元素归并。
        /// </summary>
        /// <typeparam name="T">数组元素类型。</typeparam>
        /// <param name="a">原数组。</param>
        /// <param name="aux">辅助数组。</param>
        /// <param name="lo">范围起点。</param>
        /// <param name="mid">范围中点。</param>
        /// <param name="hi">范围终点。</param>
        private void Merge<T>(T[] a, T[] aux, int lo, int mid, int hi) where T : IComparable<T>
        {
            for (int k = lo; k <= hi; k++)
            {
                aux[k] = a[k];
            }

            int i = lo, j = mid + 1;
            for (int k = lo; k <= hi; k++)
            {
                if (i > mid)
                {
                    a[k] = aux[j];
                    j++;
                }
                else if (j > hi)
                {
                    a[k] = aux[i];
                    i++;
                }
                else if (Less(aux[j], aux[i]))
                {
                    a[k] = aux[j];
                    j++;
                }
                else
                {
                    a[k] = aux[i];
                    i++;
                }
            }
        }
    }
}

 

 

2.2.10

//-----区别和注意点-----

题目

急迅合并。
兑现贰个 merge() 方法,按降序将 a[] 的后半片段复制到 aux[],
然后将其合併回 a[]
中。那样就足以去掉内循环中检验某半边是不是用尽的代码。
瞩目:那样的排序发生的结果是不安宁的(请见 2.5.1.8 节卡塔 尔(阿拉伯语:قطر‎。

//Remove()和RemoveAt()方法是直接删除

解答

合法相近给出了 java 完结,如下:

private static void merge(Comparable[] a, int lo, int mid, int hi) { 
   for (int i = lo; i <= mid; i++)
      aux[i] = a[i]; 

   for (int j = mid+1; j <= hi; j++)
      aux[j] = a[hi-j+mid+1];

   int i = lo, j = hi; 
   for (int k = lo; k <= hi; k++) 
      if (less(aux[j], aux[i])) a[k] = aux[j--];
      else                      a[k] = aux[i++];
}

C# 完结见代码部分。

//Delete()方法只是将该行标记为deleted,但是还存在,还可DataTable.RejectChanges()回滚,使该行取消删除。

代码
using System;
using Merge;

namespace _2._2._10
{
    /// <summary>
    /// 归并排序类。
    /// </summary>
    public class MergeSort : BaseSort
    {
        /// <summary>
        /// 默认构造函数。
        /// </summary>
        public MergeSort() { }

        /// <summary>
        /// 利用归并排序将数组按升序排序。
        /// </summary>
        /// <typeparam name="T">数组元素类型。</typeparam>
        /// <param name="a">待排序的数组。</param>
        public override void Sort<T>(T[] a)
        {
            T[] aux = new T[a.Length];
            Sort(a, aux, 0, a.Length - 1);
        }

        /// <summary>
        /// 自顶向下地对数组指定范围内进行归并排序,需要辅助数组。
        /// </summary>
        /// <typeparam name="T">需要排序的元素类型。</typeparam>
        /// <param name="a">原数组。</param>
        /// <param name="aux">辅助数组。</param>
        /// <param name="lo">排序范围起点。</param>
        /// <param name="hi">排序范围终点。</param>
        private void Sort<T>(T[] a, T[] aux, int lo, int hi) where T : IComparable<T>
        {
            if (hi <= lo)
                return;
            int mid = lo + (hi - lo) / 2;
            Sort(a, aux, lo, mid);
            Sort(a, aux, mid + 1, hi);
            Merge(a, aux, lo, mid, hi);
        }

        /// <summary>
        /// 将指定范围内的元素归并。
        /// </summary>
        /// <typeparam name="T">数组元素类型。</typeparam>
        /// <param name="a">原数组。</param>
        /// <param name="aux">辅助数组。</param>
        /// <param name="lo">范围起点。</param>
        /// <param name="mid">范围中点。</param>
        /// <param name="hi">范围终点。</param>
        private void Merge<T>(T[] a, T[] aux, int lo, int mid, int hi) where T : IComparable<T>
        {
            // 前半部分升序复制
            for (int k = lo; k <= mid; k++)
            {
                aux[k] = a[k];
            }
            // 后半部分降序复制
            for (int k = mid + 1; k <= hi; k++)
            {
                aux[k] = a[hi - k + mid + 1];
            }

            // i 指向最左端,j 指向最右端
            int i = lo, j = hi;
            for (int k = lo; k <= hi; k++)
            {
                if (Less(aux[j], aux[i]))
                {
                    a[k] = aux[j];
                    j--;
                }
                else
                {
                    a[k] = aux[i];
                    i++;
                }
            }
        }
    }
}

 

//用Rows.Count来获取行数时,还是删除之前的行数,需要使用DataTable.AcceptChanges()方法来提交修改。

2.2.11

//如果要删除DataTable中的多行,应该采用倒序循环DataTable.Rows,而且不能用foreach进行循环删除,因为正序删除时索引会发生变化,程式发生异常,很难预料后果。

题目

改进。
兑现 2.2.2 节所述的对归总排序的三项校勘:
加快小数组的排序速度,
检查评定数组是或不是已经稳步甚至通过在递归中调换参数来防止复制。

发表评论

电子邮件地址不会被公开。 必填项已用*标注