C#程序设计4.5 泛型和集合_第1页
C#程序设计4.5 泛型和集合_第2页
C#程序设计4.5 泛型和集合_第3页
C#程序设计4.5 泛型和集合_第4页
C#程序设计4.5 泛型和集合_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

单元4C#进阶编程知识目标(1)掌握结构化的异常处理机制;(2)深刻理解委托和事件;(3)掌握枚举和结构;(4)掌握字符串的常用方法;(5)掌握正则表达式的基本用法;(6)掌握常用的集合类和泛型集合类。能力目标(1)能够捕获并处理异常;(2)能使用枚举或结构描述数据;(3)能对文本进行较为复杂的处理;(4)能使用正则表达式实现文本的验证;(5)能定义和使用委托类型;(6)能给对象添加事件并能处理事件;(7)能使用集合类存储数据,能编写基于栈、队列、链表、哈希表等数据结构的程序。教学任务任务1异常处理任务2枚举和结构任务3委托和事件任务4字符串与正则表达式任务5泛型和集合单元4

C#进阶编程任务5泛型和集合引例实现简单迷宫。寻找一条从入口到出口的通路。知识储备知识点1:非泛型集合。知识点2:泛型概述。知识点3:泛型集合。集合概述如果对象可以提供对相关对象的引用,那么它就是一个集合,它可以遍历集合中的每个数据项;专业的说法是所有实现了System.Collections.IEnumerable接口的类的对象都是集合。数据集合类都位于System.Collections命名空间中。知识点1:非泛型集合常用集合类型1.ArrayList类2.Stack类3.Queue类4.Hashtable类集合优点数组Array是固定大小的,不能伸缩;而集合却是可变长的。数组要声明元素的类型,集合类的元素类型却是object。数组可读可写不能声明只读数组。集合类可以提供ReadOnly方法以只读方式使用集合。集合属性修改或者获取ArrayList的容量使用Capacity属性,通过设置该属性的值可以修改ArrayList的容量;读取该属性的值可以获取ArrayList的容量当为ArrayList对象添加的数据元素的个数超出初始化时指定的数据项个数时,ArrayList对象的容量还可以自动增长默认增长后的容量为原来的2倍,即数据项的个数为初始化时的2倍。ArrayList常用的属性和方法如下表所示属性说明Capacity获取或设置集合可包含的元素数Count获取集合中实际包含的元素数方法说明Add将元素添加到集合的结尾处Clear从集合中移除所有元素CopyTo将ArrayList或它的一部分复制到一维数组中Insert将元素插入到集合的指定索引处Remove从集合中移除特定值的第一个匹配项RemoveAt移除集合中指定索引处的元素Reverse将集合中元素的顺序反转Sort将集合或集合的一部分进行排序【例4-7】歌唱比赛计分器。从键盘输入评委打出的分数,去掉一个最高分和一个最低分,显示平均分。

class

Score

{

ArrayListal=new

ArrayList();

public

voidAddMark()

{

inti=0;

while(true)

{

Console.WriteLine("请输入评为分数,以-1结束");i=int.Parse(Console.ReadLine());

if(i!=-1)al.Add(i);

else

break;

}

}

public

voidDel()

{

if(al.Count>2)

{al.Sort();al.RemoveAt(0);al.RemoveAt(al.Count-1);

}

}

public

doubleAverage()

{

doublesum=0;

foreach(intiinal)

{sum+=i;

}

returnsum/al.Count;

}

}

class

Program

{

static

voidMain(string[]args)

{

Scores=new

Score();s.AddMark();s.Del();

Console.WriteLine("平均分是{0}",s.Average());

Console.ReadKey();

}

}Queue类Queue是先进先出的集合类,也成为队列。队列的特性是一端进,一端出,即先进入队列的元素将会先从出口出来。队列一般有入队和出队的操作,队列,先进先出。Enqueue方法入队列,Dequeue方法出队列。

class

Program

{

static

voidMain(string[]args)

{

Queueq=new

Queue();

Console.WriteLine("入队前,队列的大小{0}",q.Count);q.Enqueue("0001");q.Enqueue("洗发水");q.Enqueue(15);

Console.WriteLine("入队后,队列的大小{0}",q.Count);q.Dequeue();

Console.WriteLine("出对后,队列的大小{0}",q.Count);

foreach(objectiteminq)

{

Console.WriteLine("队列中的元素{0}",item);

}

Console.ReadKey();

}

}Stack类栈,后进先出。Push方法入栈,Pop方法出栈。Stack是又一重要的集合类,它的功能与Queue相似,但也有不同。它的特点是后进先出,即最后进入的元素会最先出来。堆栈一般有进栈和出栈的操作。【例4-8】实现数值进制的转换。

class

Program

{

static

stringConvert(inti,intj)

{

if(i<2||j>16)

{

return

"只能将十进制转化为二到十六进制";

}

Stackstack=new

Stack();

do

{

intk=i%j;

charc=(k<10)?(char)(k+48):(char)(k+55);stack.Push(c);}while((i=i/j)!=0);

strings="";

while(stack.Count>0)

{s+=stack.Pop().ToString();

}

returns;

}

static

voidMain(string[]args)

{

Console.WriteLine("请输入一个十进制数:");

inti=int.Parse(Console.ReadLine());

Console.WriteLine("请输入要转换的进制:");

intj=int.Parse(Console.ReadLine());

Console.WriteLine(Convert(i,j));

Console.ReadKey();

}

}HashTable类HashTable翻译为哈希表,表示键(key)/值(value)对的集合,这些键/值对根据键的哈希代码进行组织,每一个元素都是一个存储在字典实体对象中的键/值对。HashTable像一个字典,根据键可以找到相应的值。哈希表提供了添加元素和访问元素等方法,哈希表,名-值对。

class

Program

{

static

voidMain(string[]args)

{

Hashtableh=new

Hashtable(3);h.Add(1,"0001");h.Add(2,"洗发水");h.Add("decimal",15);

foreach(DictionaryEntryiteminh)

{

Console.WriteLine("{0}{1}",item.Key,item.Value);

}h.Remove("decimal");

Console.WriteLine("\n删除后的哈希表");

foreach(DictionaryEntryiteminh)

{

Console.WriteLine("{0}{1}",item.Key,item.Value);

}

Console.ReadKey();

}

}知识点2:泛型概述所谓泛型,即通过参数化类型来实现在同一份代码上操作多种数据类型,泛型编程是一种编程范式,它利用“参数化类型”将类型抽象化,从而实现更为灵活的复用。C#泛型赋予了代码更强的类型安全,更好的复用,更高的效率,更清晰的约束。泛型泛型,是指定类型的集合,是通过参数化类型来实现在同一份代码上操作多种数据的类型。泛型是在C#2.0引入的。泛型的字面意思是具有在多种数据类型上皆可操作,与模板有些相似。泛型引入了类型参数化的概念,能够实现定义的泛型类和方法将一个或多个类型的指定,推迟到客户端代码声明并实例化该类或方法的时候。在编写其他客户端代码时使用的单个类,不会引入运行时强制转换或装箱操作的成本或风险。只要提供数据类型就能使用这些强有力的数据结构。泛型的特点如果实例化泛型类型的参数相同,那么JIT编译器会重复使用该类型。C#的泛型类型可以应用于强大的反射技术。泛型无需类型的转换操作,减少了装箱和拆箱的操作,性能提高。泛型类型的声明不仅可单独声明,也可在基类中包含泛型类型的声明。使用泛型类型可以最大限度地重用代码、保护类型的安全以及提高性能。泛型最常见的用途是创建集合类。.NET2.0的System.Collections.Generics命名空间包含了泛型集合定义。各种不同的集合/容器类都被“参数化”了。为使用它们,只需简单地指定参数化的类型即可。常用泛型格式编程时需要引入System.Collection.Generic名称空间,最为常用的有以下两个:List<T>T类型对象的集合。使用方法与ArrayList类似,但它不仅比ArrayList更安全,而且明显地更加快速。Dictionary<K,V>V类型的项与K类型的键值相关的集合,可以理解Dictionary是Hashtable的泛型版本。知识点3:泛型集合创建T类型对象的泛型集合语法为:List<T>泛型对象名=newList<T>();添加泛型List<T>的数据项Add():向列表尾部添加,输入参数为T类型数据AddRange():向列表尾部添加,输入参数为T类型对象组Insert():向指定位置添加,输入数据为位置索引和要添加的对象(T类型)示例:类型安全的泛型列表在上例中,我们编写了一个泛型的列表的例子,在尖括号内指定参数类型为int。该代码的执行将产生结果“Totalis7”。现在,如果去掉语句doubleList.Add(5.0)的注释,将得到一个编译错误。编译器指出它不能发送值5.0到方法Add(),因为该方法仅接受int型。不同于前例,这里的代码实现了类型安全。

List<int>aList=new

List<int>();aList.Add(3);aList.Add(4);

//aList.Add(5.0);

inttotal=0;

foreach(intvalinaList)

{total=total+val;

}

Console.WriteLine("Totalis{0}",total);示例:创建一个泛型类

public

class

MyList<T>

{

private

static

intobjCount=0;

publicMyList()

{objCount++;}

public

intCount

{

get

{returnobjCount;}

}

}

class

SampleClass{}

class

Program

{

static

voidMain(string[]args)

{

MyList<int>myIntList=new

MyList<int>();

MyList<int>myIntList2=new

MyList<int>();

MyList<double>myDoubleList=new

MyList<double>();

MyList<SampleClass>mySampleList=new

MyList<SampleClass>();

Console.WriteLine(myIntList.Count);//输出2

Console.WriteLine(myIntList2.Count);//输出2

Console.WriteLine(myDoubleList.Count);//输出1

Console.WriteLine(mySampleList.Count);//输出1

Console.WriteLine(new

MyList<SampleClass>().Count);//输出2

Console.ReadLine();

}

}【例4-9】编程判断一个字符串是否是回文。回文是指一个字符序列以中间字符为基准两边字符完全相同,如字符序列“ACBDEDBCA”是回文算法思想:判断一个字符序列是否是回文,就是把第一个字符与最后一个字符相比较,第二个字符与倒数第二个字符比较,依次类推,第i个字符与第n-i个字符比较。如果每次比较都相等,则为回文,如果某次比较不相等,就不是回文。因此,可以把字符序列分别入队列和栈,然后逐个出队列和出栈并比较出队列的字符和出栈的字符是否相等,若全部相等则该字符序列就是回文,否则就不是回文。

class

Program

{

static

voidMain(string[]args)

{

Stack<char>s=new

Stack<char>(50);

Queue<char>q=new

Queue<char>(50);

stringstr=Console.ReadLine();

for(inti=0;i<str.Length;++i)

{s.Push(str[i]);q.Enqueue(str[i]);

}

while(s.Count!=0&&q.Count!=0)

{

if(s.Pop()!=q.Dequeue())

{

break;

}

}

if(s.Count!=0||q.Count!=0)

{

Console.WriteLine("这不是回文!");

}

else

{

Console.WriteLine("这是回文!");

}

Console.ReadKey();

}

}泛型集合Dictionary<K,V>泛型集合Dictionary<K,V>存储数据的方式和哈希表类似,通过键/值对来保存数据。它具有泛型的全部特征,编译的时候就检查类型约束,获取元素的时候无须类型转换。定义语法如下:Dictionary<K,V>t=newDictionary<K,V>();泛型提供了很好的类型安全策略,添加、删除、遍历等操作和HashTable是类似的。27引例分析与实现——简单迷宫实现迷宫问题:寻找一条从入口到出口的通路。8123456781234567入口出口前进方向:上(北)、下(南)、左(西)、右(东)东南北西

走步规则:首先从向下开始,按照逆时针方向搜索下一步可能前进的位置28栈迷宫问题8123456781234567(1,1)i(2,1)i(3,1)i(4,1)i(5,1)i(6,1)(7,1)i引例分析29栈8123456781234567(1,1)i(2,1)i(3,1)i(4,1)i(5,1)i(6,1)(7,1)i@

@

(5,2)i(5,3)i(6,3)i(6,4)i…(8,8)iiiiii引例分析迷宫问题引例实现

/*向下(南)访问*/

static

boolstepdown(inti,intj)

{i++;

if(i>=8)

return

false;

if(a[i,j]==0)

return

true;

return

false;

}

/*向右(东)访问*/

static

boolstepright(inti,intj)

{j++;

if(j>=8)

return

false;

if(a[i,j]==0)return

true;

return

false;

}/*向上(北)访问*/

static

boolstepup(inti,intj)

{i--;

if(i<0)

return

false;

if(a[i,j]==0)

return

true;

return

false;

}

/*向左(西)访问*/

static

boolstepleft(inti,intj)

{j--;

if(j<0)

return

false;

if(a[i,j]==0)

return

true;

return

false;

}

static

voidmigong(Stack<int>s)

{

inti=0,j=0,x;

while(true)

{

if(a[i,j]==0)

{s.Push((i+1)*10+j+1);a[i,j]=1;

if(s.Peek()==88)return;

}

if(stepdown(i,j))i++;

else

if(stepright(i,j)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论