Download presentation
Presentation is loading. Please wait.
Published byHendri Atmadja Modified 6年之前
1
第4章 数组和集合 4.1 一维数组 4.2 二维数组 4.3 Array类 4.4 交错数组 4.5 ArrayList类
第4章 数组和集合 4.1 一维数组 4.2 二维数组 4.3 Array类 4.4 交错数组 4.5 ArrayList类 4.6 List<T>类
2
4.1 一维数组 4.1.1 一维数组的定义 定义一维数组的语法格式如下:
4.1 一维数组 一维数组的定义 定义一维数组的语法格式如下: 数组类型[] 数组名; 例如,以下定义了3个一维数组,即整型数组a、双精度数组b和字符串数组c。 int[] a; double[] b; string[] c; 在定义数组后,必须对其进行初始化才能使用。初始化数组有两种方法:动态初始化和静态初始化。
3
4.1.2 一维数组的动态初始化 动态初始化需要借助new运算符,为数组元素分配内存空间,并为数组元素赋初值,数值类型初始化为0,布尔类型初始化为false,字符串类型初始化为null。 动态初始化数组的格式如下: 数组类型[] 数组名=new 数据类型[n]{元素值0,元素值1,,元素值n-1}; 其中,“数组类型”是数组中数据元素的数据类型,n为“数组长度”,可以是整型常量或变量,后面一层大括号里为初始值部分。
4
1. 不给定初始值的情况 如果不给出初始值部分,各元素取默认值。例如: int[] a = new int[10]; 该数组在内存中各数组元素均取默认值0。
5
2. 给定初始值的情况 如果给出初始值部分,各元素取相应的初值,而且给出的初值个数与“数组长度”相等。 此时可以省略“数组长度”,因为后面的大括号中已列出了数组中的全部元素。
6
在这种情况下,不允许“数组长度”为变量,例如: int n = 5; //定义变量n
int[] a = new int[10]{1,2,3,4,5,6,7,8,9,10}; 或 int[] a = new int[]{1,2,3,4,5,6,7,8,9,10}; 在这种情况下,不允许“数组长度”为变量,例如: int n = 5; //定义变量n int[] myarr = new int[n] {1,2,3,4,5}; //错误 如果给出“数组长度”,则初始值的个数应与“数组长度”相等,否则出错。例如: int[] mya = new int[2] {1,2}; //正确 int[] mya = new int[2] {1,2,3}; //错误 int[] mya = new int[2] {1}; //错误
7
4.1.3 一维数组的静态初始化 静态初始化数组时,必须与数组定义结合在一起,否则会出错。静态初始化数组的格式如下:
数据类型[] 数组名={元素值0,元素值1,,元素值n-1}; 用这种方法对数组进行初始化时,无需说明数组元素的个数,只需按顺序列出数组中的全部元素即可,系统会自动计算并分配数组所需的内存空间。
8
例如,以下是对整型数组myarr的静态初始化:
int[] myarr={1,2,3,4,5}; 在这种情况下,不能将数组定义和静态初始化分开,例如,以下是错误的。 int[] myarr; myarr={1,2,3,4,5}; //错误的数组的静态初始
9
4.1.4 访问一维数组中的元素 访问一维数组中的某个元素:名称[下标或索引]。
访问一维数组中的元素 访问一维数组中的某个元素:名称[下标或索引]。 所有元素下标从0开始,到数组长度减1为止。例如,以下语句输出数组myarr的所有元素值: for (i=0;i<5;i++) Console.Write("{0} ",a[i]); Console.WriteLine();
10
C#还提供foreach语句。该语句提供一种简单、明了的方法来循环访问数组的元素。例如,以下代码定义一个名称为mya的数组,并用foreach语句循环访问该数组。
int[] mya = {1,2,3,4,5,6}; foreach (int i in mya) System.Console.Write("{0} ",i); Console.WriteLine(); 输出为: 。
11
4.1.5 一组数组的越界 若有如下语句定义并初始化数组ca:
一组数组的越界 若有如下语句定义并初始化数组ca: int[] ca = new int[10]{1,2,3,4,5,6,7,8,7,9,10}; 数组ca的合法下标为0~9,如果程序中使用ca[10]或ca[50],则超过了数组规定的下标,因此越界了。C#系统会提示以下出错信息。 未处理的异常: System.IndexOutOfRangeException:索引超出了数组界限。
12
【例4.1】设计一个控制台应用程序,采用二分查找方法在给定的有序数组a中查找用户输入的值,并提示相应的查找结果。
using System; namespace proj4_1 { class Program { static void Main(string[] args) { double [] a=new double[10]{0,1.2,2.5,3.1,4.6,4.0,6.7,7.6,8.2,9.8}; double k; int low=0,high=9,mid; Console.Write("k:"); k=double.Parse(Console.ReadLine()); while (low<=high) { mid=(low+high)/2; if (a[mid] == k) { Console.WriteLine("a[{0}]={1}", mid, k); return } else if (a[mid] > k) high = mid - 1; else low = mid + 1; Console.WriteLine("未找到{0}",k);
13
4.2 二维数组 4.2.1 二维数组的定义 定义二维数组的语法格式如下:
4.2 二维数组 二维数组的定义 定义二维数组的语法格式如下: 数组类型[,] 数组名; 其中,“数据类型”为C#中合法的数据类型,“数组名”为C#中合法的标识符。
14
例如,以下语句定义了3个二维数组,即整型数组x、双精度数组y和字符串数组z。
int[,] x; double[,] y; string[,] z; 对于多维数组,可以作类似的推广,例如,以下语句定义了一个三维数组p。 int[,,] p;
15
4.2.2 二维数组的动态初始化 动态初始化二维数组的格式如下:
数据类型[,] 数组名=new 数据类型[m][n]{ {元素值0,0,元素值0,1,,元素值0,n-1}, {元素值1,0,元素值1,1,,元素值1,n-1}, {元素值m-1,0,元素值m-1,1,,元素值m-1,n-1} }; 其中,“数组类型”是数组中数据元素的数据类型,m、n分别为行数和列数,即各维的长度,可以是整型常量或变量。
16
1. 不给定初始值的情况 如果不给出初始值部分,各元素取默认值。例如: int[,] x = new int[2,3]; 该数组各数组元素均取默认值0。
17
2. 给定初始值的情况 如果给出初始值部分,各元素取相应的初值,而且给出的初值个数与对应的“数组长度”相等。此时可以省略“数组长度”,因为后面的大括号中已列出了数组中的全部元素。例如: int[,] x = new int[2,3]{{1,2,3},{4,5,6}}; 或 int[,] x = new int[,]{{1,2,3},{4,5,6}};
18
4.2.3 二维数组的静态初始化 静态初始化数组时,必须与数组定义结合在一起,否则会出错。静态初始化数组的格式如下:
数据类型[,] 数组名={{元素值0,0,元素值0,1,,元素值0,n-1}, {元素值1,0,元素值1,1,,元素值1,n-1}, {元素值m-1,0,元素值m-1,1,,元素值m-1,n-1}}; 例如,以下语句是对整型数组myarr的静态初始化。 int[,] myarr={{1,2,3},{4,5,6}};
19
访问二维数组中的元素 为了访问二维数组中的某个元素,需指定数组名称和数组中该元素的行下标和列下标。例如,以下语句输出数组d的所有元素值。 int[,] d = new int[2,3]{{1,2,3},{4,5,6}}; int i,j; for (i=0;i<2;i++) for (j=0;j<3;j++ Console.Write("{0} ",d[i,j]); Console.WriteLine();
20
对于多维数组,也可以使用foreach语句来循环访问每一个元素,例如:
int[,] myb = new int[3, 2] { {1, 2}, {3,4}, {5,6}}; foreach (int i in myb) Console.Write("{0} ", i); Console.WriteLine(); 其输出为: 。
21
【例4.2】设计一个控制台应用程序,输出九行杨辉三角形。
using System; namespace proj4_2 { class Program { const int N=10; static void Main(string[] args) { int i,j; int[,] a=new int[N,N]; for (i=1;i<N;i++) //1列和对角线元素均为1 { a[i,i]=1; a[i,1]=1; } for (i=3;i<N;i++) //求第3~N行的元素值 for (j=2;j<=i-1;j++) a[i,j]=a[i-1,j-1]+a[i-1,j]; for (i=1;i<N;i++) //输出数序 { for (j=1;j<=i;j++) Console.Write("{0,-2} ",a[i,j]); Console.WriteLine(); } }}}
22
4.4 交错数组 交错数组:元素为数组的数组,元素的维度和大小可以不同。 多维数组:元素的维度和大小的均相同。
23
4.4.1 交错数组的定义和初始化 以下语句定义了一个由3个元素组成的一维数组,其中每个元素都是一个一维整数数组:
以下语句定义了一个由3个元素组成的一维数组,其中每个元素都是一个一维整数数组: int[][] arrj = new int[3][]; 必须初始化arrj的元素后才可以使用它。可以如下所示初始化该元素: arrj[0] = new int[5]; arrj[1] = new int[4]; arrj[2] = new int[2]; int [][] b = new int[][]{new int[]{1,2,4}, new int[]{2,4,5}, new int[]{9,8,0}}; int[][] c={new int[]{1,2,4}, new int[]{2,4,5}, new int[]{9,8,0}}; int[][] d=new int[3][4]; (错)
24
交错数组a在内存中的存储方式
25
4.4.2 访问交错数组中的元素 交错数组元素的访问方式与多维数组类似,通常使用Length方法返回包含在交错数组中的数组的数目。
26
例如,以下程序定义一个交错数组myarr并初始化,最后输出所有元素的值。
int[][] myarr = new int[3][]; myarr[0] = new int[] {1,2,3,4,5,6}; myarr[1] = new int[] {7,8,9,10}; myarr[2] = new int[] {11,12}; for (int i = 0; i < myarr.Length; i++) { Console.Write("myarr({0}): ", i); for (int j = 0; j < myarr[i].Length; j++) Console.Write("{0} ", myarr[i][j]); Console.WriteLine(); } 程序运行结果如下: myarr(0): myarr(1): myarr(2): 11 12
27
4.3 Array类 Array类是所有数组类型的抽象基类型。 属性 说明 Length
LongLength 获得一个64位整数,该整数表示Array的所有维数中元素的总数。 Rank 获取Array的秩(维数)。
28
方法 说明 BinarySearch 静态方法。使用二进制搜索算法在一维的排序Array中搜索值。 Copy 静态方法。将一个Array的一部分元素复制到另一个Array中,并根据需要执行类型强制转换和装箱。 CopyTo 非静态方法。将当前一维Array的所有元素复制到指定的一维Array中。 Find 静态方法。搜索与指定谓词定义的条件匹配的元素,然后返回整个Array中的第一个匹配项。 ForEach 静态方法。对指定数组的每个元素执行指定操作。 GetLength 非静态方法。获取一个32位整数,该整数表示Array的指定维中的元素数。 GetLongLength 非静态方法。获取一个64位整数,该整数表示Array的指定维中的元素数。 GetLowerBound 非静态方法。获取Array中指定维度的下限。 GetUpperBound 非静态方法。获取Array的指定维度的上限。 GetValue 非静态方法。获取当前Array中指定元素的值。 IndexOf 静态方法。返回一维Array或部分Array中某个值第一个匹配项的索引。 Resize 静态方法。将数组的大小更改为指定的新大小。 Reverse 静态方法。反转一维Array或部分Array中元素的顺序。 SetValue 非静态方法。将当前Array中的指定元素设置为指定值。 Sort 静态方法。对一维Array对象中的元素进行排序。
29
【例4.3】设计一个控制台应用程序,产生10个0~19的随机整数,对其递增排序并输出。
using System; namespace proj4_3 { class Program { static void Main(string[] args) { int i,k; int[] myarr = new int[10]; //定义一个一维数组 Random randobj = new Random(); //定义一个随机对象 for (i = myarr.GetLowerBound(0); i <= myarr.GetUpperBound(0); i++) { k=randobj.Next() % 20; //返回一个0~19的正整数 myarr.SetValue(k, i); //给数组元素赋值 } Console.Write("随机数序:"); for (i = myarr.GetLowerBound(0); i <=myarr.GetUpperBound(0); i++) Console.Write("{0} ", myarr.GetValue(i)); Console.WriteLine(); Array.Sort(myarr); //数组排序 Console.Write("排序数序:"); }}}
30
4.5 ArrayList类(动态数组) ArrayList类(在命名空间System.Collections中),用于建立不定长度的数组,由于该类数组的数据类型为Object,其长度不固定,可以将其对象看成是一个集合。 定义ArrayList类的对象的语法格式如下: ArrayList 数组名 = new ArrayList(); 例如,以下语句定义一个ArrayList类的对象myarr,可以将它作为一个数组使用: ArrayList myarr = new ArrayList();
31
属性 说明 Capacity 获取或设置ArrayList可包含的元素数。 Count 获取ArrayList中实际包含的元素数。 Item 获取或设置指定索引处的元素。
32
方法 说明 Add 将对象添加到ArrayList的结尾处。 AddRange 将一个ICollection对象的元素添加到ArrayList的末尾。 BinarySearch 使用二分检索算法在已排序的ArrayList或它的一部分中查找特定元素。 Clear 从ArrayList中移除所有元素。 Clone 创建ArrayList的浅表副本。 Contains 确定某元素是否在ArrayList中。 CopyTo 将ArrayList或它的一部分复制到一维数组中。 GetRange 返回 ArrayList,它表示源ArrayList中元素的子集。 IndexOf 返回ArrayList或它的一部分中某个值的第一个匹配项的从零开始的索引。 Insert 将元素插入ArrayList的指定索引处。 InsertRange 将集合中的某个元素插入ArrayList的指定索引处。 LastIndexOf 返回ArrayList或它的一部分中某个值的最后一个匹配项的从零开始的索引。 Remove 从ArrayList中移除特定对象的第一个匹配项。 RemoveAt 移除ArrayList的指定索引处的元素。 RemoveRange 从ArrayList中移除一定范围的元素。 Reverse 将ArrayList或它的一部分中元素的顺序反转。 SetRange 将集合中的元素复制到ArrayList中一定范围的元素上。 Sort 对ArrayList或它的一部分中的元素进行排序。 ToArray 将ArrayList的元素复制到新数组中。 ToString 返回表示当前Object的String。 TrimToSize 将容量设置为ArrayList中元素的实际数目。
33
【例4.4】 定义一个ArrayList对象,用于存放若干个姓名,对其进行排序,并输出排序后的结果。
using System; using System.Collections; //新增 namespace proj4_4 { class Program { static void Main(string[] args) { ArrayList myarr = new ArrayList(); myarr.Add("Smith"); myarr.Add("Mary"); myarr.Add("Dava"); myarr.Add("John"); Console.Write("排序前序列:"); foreach(String sname in myarr) Console.Write(sname + " "); Console.WriteLine(); myarr.Sort(); Console.Write(“排序后序列:"); } }}
34
4.6 List<T>类 List<T>类是ArrayList类的泛型等效类,该类使用大小可按需动态增加的数组实现IList泛型接口。 定义List<T>类的对象的语法格式如下: List<T> 数组名 = new List<T>(); 例如,以下语句定义一个List<string>类的对象myset,其元素类型为string,可以将它作为一个数组使用: List<string> myset = new List<string>();
35
属性 说明 Capacity 获取或设置该内部数据结构在不调整大小的情况下能够保存的元素总数。 Count 获取List中实际包含的元素数。 Item 获取或设置指定索引处的元素。
36
方法 说明 Add 将对象添加到List的结尾处。 AddRange 将指定集合的元素添加到List的末尾。 BinarySearch 使用对分检索算法在已排序的List或它的一部分中查找特定 元素。 Clear 从List中移除所有元素。 Contains 确定某元素是否在List中。 CopyTo 将List或它的一部分复制到一个数组中。 Exists 确定List是否包含与指定谓词所定义的条件相匹配的元素。 Find 搜索与指定谓词所定义的条件相匹配的元素,并返回整个 List中的第一个匹配元素。 FindAll 检索与指定谓词所定义的条件相匹配的所有元素。 FindIndex 搜索与指定谓词所定义的条件相匹配的元素,返回List或它 的一部分中第一个匹配项的从零开始的索引。 FindLast List中的最后一个匹配元素。
37
方法 说明 FindLastIndex 搜索与指定谓词所定义的条件相匹配的元素,返回List或它的一部分中最后一个匹配项的从零开始的索引。 ForEach 对List的每个元素执行指定操作。 IndexOf 返回List或它的一部分中某个值的第一个匹配项的从零开始的索引。 Insert 将元素插入List的指定索引处。 InsertRange 将集合中的某个元素插入List的指定索引处。 LastIndexOf 返回List或它的一部分中某个值的最后一个匹配项的从零开始的索引。 Remove 从List中移除特定对象的第一个匹配项。 RemoveAll 移除与指定的谓词所定义的条件相匹配的所有元素。 RemoveAt 移除List的指定索引处的元素。 RemoveRange 从List中移除一定范围的元素。 Reverse 将List或它的一部分中元素的顺序反转。 Sort 对List或它的一部分中的元素进行排序。 ToArray 将List的元素复制到新数组中。 TrimExcess 将容量设置为List中的实际元素数目(如果该数目小于某个阈值)。
38
【例4.5】设计一个控制台应用程序,定义一个List<T>对象,用于添加若干个学生的学号和姓名,输出后再插入一个学生记录。
using System; namespace proj4_5 { struct Stud //定义结构类型 { public int sno; //学号 public string sname; //姓名 }; class Program { static void Main(string[] args) { int i; List<Stud> myset = new List<Stud>(); Stud s1 = new Stud(); s1.sno = 101;s1.sname = "李明"; myset.Add(s1); Stud s2 = new Stud(); s2.sno = 103; s2.sname = "王华"; myset.Add(s2);
39
Stud s3 = new Stud(); s3.sno = 108; s3.sname = "张英"; myset.Add(s3); Stud s4 = new Stud(); s4.sno = 105; s4.sname = "张伟"; myset.Add(s4); Console.WriteLine("元素序列:"); Console.WriteLine(" 下标 学号 姓名"); i = 0; foreach (Stud st in myset) { Console.WriteLine(" {0} {1} {2}", i,st.sno, st.sname); i++; } Console.WriteLine("容量: {0}", myset.Capacity); Console.WriteLine("元素个数: {0}", myset.Count); Console.WriteLine("在索引2处插入一个元素"); Stud s5 = new Stud(); s4.sno = 106; s4.sname = "陈兵";
40
myset.Insert(2, s5); Console.WriteLine("元素序列:"); Console.WriteLine(" 下标 学号 姓名"); i = 0; foreach (Stud st in myset) { Console.WriteLine(" {0} {1} {2}", i, st.sno, st.sname); i++; }
Similar presentations