塔 · 第 一 条 约 定
Array类:
1、关于Array类的一些小知识:
<1>数组是一个存储相同类型元素的固定大小的顺序集合。数组是用来存储数据的集合,通常认为数组是一个同一类型变量的集合。
<2>声明数组变量并不是声明 number0、number1、...、number99 一个个单独的变量,而是声明一个就像 numbers 这样的变量,然后使用 numbers[0]、numbers[1]、...、numbers[99] 来表示一个个单独的变量。数组中某个指定的元素是通过索引来访问的。
<3>所有的数组都是由连续的内存位置组成的。最低的地址对应第一个元素,最高的地址对应最后一个元素。
2、Array类的声明
在 C# 中声明一个数组,可以使用下面的语法:
一维 datatype[] arrayName; //datatype是数据类型的意思,比如int double等
二维 datatype[,] arrayName; //datatype是数据类型的意思,比如int double等
3、Array类的初始化
声明一个数组不会在内存中初始化数组。当初始化数组变量时,可以赋值给数组。
数组是一个引用类型,所以您需要使用 new 关键字来创建数组的实例。
例如:
double[] balance = new double[10];
4、Array类的赋值
<1>可以通过使用索引号赋值给一个单独的数组元素,比如:
double[] balance = new double[10];
balance[0] = 4500.0;
<2>可以在声明数组的同时给数组赋值,比如:
double[] balance = { 2340.0, 4523.69, 3421.0};
<3>也可以创建并初始化一个数组,比如:
int [] marks = new int[5] { 99, 98, 92, 97, 95};
<4>在上述情况下,也可以省略数组的大小,比如:
int [] marks = new int[] { 99, 98, 92, 97, 95};
您也可以赋值一个数组变量到另一个目标数组变量中。在这种情况下,目标和源会指向相同的内存位置:
int [] marks = new int[] { 99, 98, 92, 97, 95};
int[] score = marks;
当您创建一个数组时,C# 编译器会根据数组类型隐式初始化每个数组元素为一个默认值。例如,int 数组的所有元素都会被初始化为 0。
5、Array类的常用属性
序号 | 属性 & 描述 |
---|---|
1 | IsFixedSize 获取一个值,该值指示数组是否带有固定大小。 |
2 | IsReadOnly 获取一个值,该值指示数组是否只读。 |
3 | Length 获取一个 32 位整数,该值表示所有维度的数组中的元素总数。 |
4 | LongLength 获取一个 64 位整数,该值表示所有维度的数组中的元素总数。 |
5 | Rank 获取数组的秩(维度)。 |
用例:
int[] marks = new int[] { 99, 98, 92, 97, 95 }; bool a = marks.IsFixedSize; bool b = marks.IsReadOnly; int c = marks.Length; int d = marks.Rank; Console.WriteLine(a); Console.WriteLine(b); Console.WriteLine(c); Console.WriteLine(d); Console.ReadKey(); //输出结果分别是 True False 5 1
6、Array类的常用方法
1 | Clear 根据元素的类型,设置数组中某个范围的元素为零、为 false 或者为 null。 |
2 | |
3 | CopyTo(Array, Int32) 从当前的一维数组中复制所有的元素到一个指定的一维数组的指定索引位置。索引由一个 32 位整数指定。 |
4 | GetLength 获取一个 32 位整数,该值表示指定维度的数组中的元素总数。 |
5 | GetLongLength 获取一个 64 位整数,该值表示指定维度的数组中的元素总数。 |
6 | GetLowerBound 获取数组中指定维度的下界。 |
7 | GetType 获取当前实例的类型。从对象(Object)继承。 |
8 | GetUpperBound 获取数组中指定维度的上界。 |
9 | GetValue(Int32) 获取一维数组中指定位置的值。索引由一个 32 位整数指定。 |
10 | IndexOf(Array, Object) 搜索指定的对象,返回整个一维数组中第一次出现的索引。 |
11 | Reverse(Array) 逆转整个一维数组中元素的顺序。 |
12 | SetValue(Object, Int32) 给一维数组中指定位置的元素设置值。索引由一个 32 位整数指定。 |
13 | |
14 | ToString 返回一个表示当前对象的字符串。从对象(Object)继承。 |
用例:
int[] marks = new int[] { 99, 98, 92, 97, 95 }; int[] marks1 = new int[5]; marks.CopyTo(marks1, 0); for (int i = 0; i < marks1.Length; i++) { Console.WriteLine(marks1[i]);//输出结果为marks数组里的数 }
int[] marks = new int[] { 99, 98, 92, 97, 95 }; object a = marks.GetType(); Console.WriteLine(a);//输出结果为System.Int 32[]
int[] marks = new int[] { 99, 98, 92, 97, 95 }; int a = marks.GetUpperBound(0); int b = marks.GetLowerBound(0); Console.WriteLine(a); //输出为4 即 marks[4] Console.WriteLine(b);//输出为0 即 marks[0]
int[] marks = new int[] { 99, 98, 92, 97, 95 }; marks.SetValue(3, 0); Console.WriteLine(marks[0]);//输出结果为3 99被替换成3
个人体会:Array数组的索引值和值之间是可以存在某种数量关系的,最简单的关系应该就是索引值0表示第1个数,索引值为1表示第2个数。
较复杂一点关系可以像背包问题中,用索引值表示负重。。。。。不知道怎么用语言说了。。。
ArrayList类:
1、使用前提
using System.Collections;//在C#中使用ArrayList必须引用Collections类
2、ArrayList小知识
它表示可单独被索引的对象的有序集合。它基本上是一种替代数组。但是不像数组,可以在指定位置添加和删除利用指数从列表中的项目,并且数组能自动调整本身大小。它也允许动态存储器分配,添加,搜索和排序列表中的项目。
3、ArrayList元素的添加
<1>用数组进行赋值
int[] arr = new int[] { 1,2,3,4,5}; ArrayList list = new ArrayList(arr);
<2>使用add方法添加
for (int i = 1; i < 5; i++) { list.Add(i+arr.Length); }
<3>使用Insert方法添加
list.Insert(5,6);//前面是索引 后面是值 结果是list[5]=6,原理是将从list[5]开始之后的数都往后移一位,然后在list[5]的位置插入元素
<4>使用InsertRange方法添加
int[] marks = new int[] { 99, 98, 92, 97, 95 }; ArrayList list = new ArrayList(marks); ArrayList list1 = new ArrayList(); list1.Add(3); list1.Add(4); list.InsertRange(0, list1); Console.WriteLine(list[1]);//输出结果为4 Console.WriteLine(list[2]);//输出结果为99 //原先为 99 98 92 97 95 //调用方法后为 3 4 99 98 92 97 95
4、ArrayList元素的删除
<1>使用Remove方法删除第一个匹配项
int[] marks = new int[] { 99, 98, 92, 97, 95 }; ArrayList list = new ArrayList(marks); list.Remove(98); //从前往后查找98这个元素,删除第一个匹配项 Console.WriteLine(list[1]);//输出结果为92 会自动前移
<2>使用RemoveAt方法删除指定索引位置的元素
int[] marks = new int[] { 99, 98, 92, 97, 95 }; ArrayList list = new ArrayList(marks); list.RemoveAt(1);//删除list[1] Console.WriteLine(list[1]);
<3>使用RemoveRange删除
list.RemoveRange(0, 3);//前面是索引后面也是索引值 删除list[0]至list[3]间的元素
5、ArrayList的遍历
ArrayList arr = new ArrayList(); arr.Add("C#学习"); arr.Add("努力学习C#"); foreach (string i in arr) //ArrayList里面装字符串类型的元素 所以就用string { Console.WriteLine(i); }
6、ArrayList元素的查找
Console.WriteLine(list.IndexOf(3));//使用IndexOf方法查找,返回值为坐标,一维坐标即点 Console.WriteLine(list.Contains(8));//使用Contains方法查找,返回值True/False
7、ArrayList的常用属性
Capacity | 获取或设置ArrayList可以包含的元素数量 |
Count | 获取实际ArrayList中包含的元素数量 |
IsFixedSize | 获取一个用以指示ArrayList是否具有固定大小 |
IsReadOnly | 获取一个值,指示ArrayList是否为只读 |
8、ArrayList的常用方法
Sort();
排序ArrayList中的元素
Reverse();
反转 ArrayList 元素的顺序
TrimToSize();
设置ArrayList中元素的实际数量
Clear();
将删除ArrayList中的所有元素
还有些方法见上面添加、删除等操作
Stack(栈)
1、特点:后进先出 即后添加的元素先出栈
2、Stack 添加元素
<1>用数组进行赋值
int[] marks = new int[] { 99, 98, 92, 97, 95 }; Stack st = new Stack(marks); Console.WriteLine(st.Peek());//输出结果为95
<2>用Push往栈顶添加元素
st.Push(5);//添加元素5
3、Stack常用属性
Count | 获取 Stack 中包含的元素个数。 |
4、Stack常用方法
Clear();
从 Stack 中移除所有的元素。
Contains( object obj );
判断某个元素是否在 Stack 中
Peek();
返回在 Stack 的顶部的对象,但不移除它
Pop();
移除并返回在 Stack 的顶部的对象。
Push( object obj );
向 Stack 的顶部添加一个对象。
ToArray();
复制 Stack 到一个新的数组中。
个人感想:和C++里的差不多,挺适合括号配对那类的配对问题
Queue类
1、特点:先进先出 即先添加的元素先出队列 就像排队一样
能接受null值,并且允许重复的元素。
2、Queue 添加元素
<1>用数组进行赋值
int[] marks = new int[] { 99, 98, 92, 97, 95 }; Queue qu = new Queue(marks); Console.WriteLine(qu.Peek());
<2>使用EnQueue
3、Queue常用属性
获取 Queue 中包含的元素数。 |
4、Queue常用方法
Void Clear() |
从 Queue 中移除所有对象。 |
Bool Contains(object obj) |
确定某元素是否在 Queue 中。 |
Object Clone() |
创建 Queue 的浅表副本。 |
Void CopyTo(Array array,int index) |
从指定数组索引开始将 Queue 元素复制到现有一维 Array 中。 |
Object Dequeue() |
移除并返回位于 Queue 开始位置的对象。 |
Void Enqueue(object obj) |
将对象添加到 Queue 的结尾处。 |
Object Peek() |
返回位于 Queue 开始处的对象但不将其移除。 |
Object[]ToArray() |
将 Queue 元素复制到新数组。 |
Void TrimToSize() |
将容量设置为 Queue 中元素的实际数目。 |
用例
static void Main(string[] args) { //创建一个队列 Queue myQ = new Queue(); myQ.Enqueue("The");//入队 myQ.Enqueue("quick"); myQ.Enqueue("brown"); myQ.Enqueue("fox"); myQ.Enqueue(null);//添加null myQ.Enqueue("fox");//添加重复的元素 // 打印队列的数量和值 Console.WriteLine("myQ"); Console.WriteLine("\tCount: {0}", myQ.Count); // 打印队列中的所有值 Console.Write("Queue values:"); PrintValues(myQ); // 打印队列中的第一个元素,并移除 Console.WriteLine("(Dequeue)\t{0}", myQ.Dequeue()); // 打印队列中的所有值 Console.Write("Queue values:"); PrintValues(myQ); // 打印队列中的第一个元素,并移除 Console.WriteLine("(Dequeue)\t{0}", myQ.Dequeue()); // 打印队列中的所有值 Console.Write("Queue values:"); PrintValues(myQ); // 打印队列中的第一个元素 Console.WriteLine("(Peek) \t{0}", myQ.Peek()); // 打印队列中的所有值 Console.Write("Queue values:"); PrintValues(myQ); Console.ReadLine(); } public static void PrintValues(IEnumerable myCollection) { foreach (Object obj in myCollection) Console.Write(" {0}", obj); Console.WriteLine(); }
Hashtable类
1、使用前提
using System.Collections;//在C#中使用ArrayList必须引用Collections类
2、用处
用于快速查找
3、什么情况下使用哈希表
(1)某些数据会被高频率查询
(2)数据量大
(3)查询字段包含字符串类型
(4)数据类型不唯一
4、哈希表的简单操作
Hashtable hshTable = new Hashtable(); // 创建哈希表
hshTable .Add("Person1", "zhanghf"); // 往哈希表里添加键值对
hshTable .Clear(); //移除哈希表里所有的键值对
hshTable .Contains("Person1"); //判断哈希表里是否包含该键
string name = (string)hshTable["Person1"].ToString(); //取哈希表里指定键的值
hshTable.Remove("Person1"); // 删除哈希表里指定键的键值对
IDictionaryEnumerator en = hshTable.GetEnumerator(); // 遍历哈希表所有的键,读出相应的值
while (en.MoveNext())
{
string str = en.Value.ToString();
}
用例:
static void Main(string[] args) { // 创建一个Hashtable实例 Hashtable ht=new Hashtable(); // 添加keyvalue键值对 ht.Add("A","1"); ht.Add("B","2"); ht.Add("C","3"); ht.Add("D","4"); // 遍历哈希表 foreach (DictionaryEntry de in ht) { Console.WriteLine("Key -- {0}; Value --{1}.", de.Key, de.Value); } // 哈希表排序 ArrayList akeys=new ArrayList(ht.Keys); akeys.Sort(); foreach (string skey in akeys) { Console.WriteLine("{0, -15} {1, -15}", skey, ht[skey]); } // 判断哈希表是否包含特定键,其返回值为true或false if (ht.Contains("A")) Console.WriteLine(ht["A"]); // 给对应的键赋值 ht["A"] ="你好"; // 移除一个keyvalue键值对 ht.Remove("C"); // 遍历哈希表 foreach (DictionaryEntry de in ht) { Console.WriteLine("Key -- {0}; Value --{1}.", de.Key, de.Value); } // 移除所有元素 ht.Clear(); // 此处将不会有任何输出 Console.WriteLine(ht["A"]); Console.ReadKey(); }
Dictionary类
1、说明
必须包含名空间System.Collection.Generic
Dictionary里面的每一个元素都是一个键值对(由二个元素组成:键和值)
键必须是唯一的,而值不需要唯一的
键和值都可以是任何类型(比如:string, int, 自定义类型,等等)
通过一个键读取一个值的时间是接近O(1)
键值对之间的偏序可以不定义
2、定义
Dictionary<datetype, datetype> openWith = new Dictionary<datetype, datetype>();
前面是键后面是值
3、字典类常用属性
Comparer 获取用于确定字典中的键是否相等的 IEqualityComparer<T>。
Count 获取包含在 Dictionary<TKey, TValue> 中的键/值对的数目。
Item 获取或设置与指定的键相关联的值。
Keys 获取包含 Dictionary<TKey, TValue> 中的键的集合。
Values 获取包含 Dictionary<TKey, TValue> 中的值的集合。
4、字典类常用方法
Add 将指定的键和值添加到字典中。
Clear 从 Dictionary<TKey, TValue> 中移除所有的键和值。
ContainsKey 确定 Dictionary<TKey, TValue> 是否包含指定的键。
ContainsValue 确定 Dictionary<TKey, TValue> 是否包含特定值。
Equals(Object) 确定指定的 Object 是否等于当前的 Object。 (继承自 Object。)
Finalize 允许对象在“垃圾回收”回收之前尝试释放资源并执行其他清理操作。 (继承自 Object。)
GetEnumerator 返回循环访问 Dictionary<TKey, TValue> 的枚举器。
GetHashCode 用作特定类型的哈希函数。 (继承自 Object。)
GetObjectData 实现 System.Runtime.Serialization.ISerializable 接口,并返回序列化 Dictionary<TKey, TValue> 实例所需的数据。
GetType 获取当前实例的 Type。 (继承自 Object。)
MemberwiseClone 创建当前 Object 的浅表副本。 (继承自 Object。)
OnDeserialization 实现 System.Runtime.Serialization.ISerializable 接口,并在完成反序列化之后引发反序列化事件。
Remove 从 Dictionary<TKey, TValue> 中移除所指定的键的值。
ToString 返回表示当前对象的字符串。 (继承自 Object。)
TryGetValue 获取与指定的键相关联的值。
5、使用方法
//定义 Dictionary<string, string> openWith = new Dictionary<string, string>();
//添加元素 openWith.Add("txt", "notepad.exe"); openWith.Add("bmp", "paint.exe"); openWith.Add("dib", "paint.exe"); openWith.Add("rtf", "wordpad.exe");
//取值 Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);//根据键取值
//更改值 openWith["rtf"] = "winword.exe"; Console.WriteLine("For key = \"rtf\", value = {0}.", openWith["rtf"]);//根据键改变值
//遍历key foreach (string key in openWith.Keys) { Console.WriteLine("Key = {0}", key); }
/遍历value foreach (string value in openWith.Values) { Console.WriteLine("value = {0}", value); } //遍历value, Second Method Dictionary<string, string>.ValueCollection valueColl = openWith.Values; foreach (string s in valueColl) { Console.WriteLine("Second Method, Value = {0}", s); }
//遍历字典 foreach (KeyValuePair<string, string> kvp in openWith) { Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value); }
//添加存在的元素 try { openWith.Add("txt", "winword.exe"); } catch (ArgumentException) { Console.WriteLine("An element with Key = \"txt\" already exists."); }
//删除元素 openWith.Remove("doc"); if (!openWith.ContainsKey("doc")) { Console.WriteLine("Key \"doc\" is not found."); }
//判断键存在 if (openWith.ContainsKey("bmp")) // True { Console.WriteLine("An element with Key = \"bmp\" exists."); }
参数为其它类型
//参数为其它类型 Dictionary<int, string[]> OtherType = new Dictionary<int, string[]>(); OtherType.Add(1, "1,11,111".Split(',')); OtherType.Add(2, "2,22,222".Split(',')); Console.WriteLine(OtherType[1][2]);
参数为自定义类型
首先定义类
class DouCube { public int Code { get { return _Code; } set { _Code = value; } } private int _Code; public string Page { get { return _Page; } set { _Page = value; } } private string _Page; }
然后
//声明并添加元素 Dictionary<int, DouCube> MyType = new Dictionary<int, DouCube>(); for (int i = 1; i <= 9; i++) { DouCube element = new DouCube(); element.Code = i * 100; element.Page = "http://www.doucube.com/" + i.ToString() + ".html"; MyType.Add(i, element); }
//遍历元素 foreach (KeyValuePair<int, DouCube> kvp in MyType) { Console.WriteLine("Index {0} Code:{1} Page:{2}", kvp.Key, kvp.Value.Code, kvp.Value.Page); }
For的用法
格式(for循环四要素:初始条件、循环条件、循环体、状态改变)
for (int i=1<初始条件>;i<=n<循环条件>;i++<状态改变>)
{
<循环体>
}
Foreach的用法
1、介绍
foreach循环用于列举出集合中所有的元素,foreach语句中的表达式由关键字in隔开的两个项组成。in右边的项是集合名,in左边的项是变量名,用来存放该集合中的每个元素。
该循环的运行过程如下:每一次循环时,从集合中取出一个新的元素值。放到只读变量中去,如果括号中的整个表达式返回值为true,foreach块中的语句就能够执行。一旦集合中的元素都已经被访问到,整个表达式的值为false,控制流程就转入到foreach块后面
的执行语句。
2、什么时候使用
当维数较多时,比如遍历二维数组,要用2个for循环 但是只要用一个foreach
3、使用方法
foreach(type 一个type类型的变量 in 数组名)
int[,,] a = new int[2, 2, 2] { {{ 1, 2 }, { 3,4}},{{ 5, 6 }, { 7,8}} };//定义一个2行2列2纵深的3维数组a foreach(int i in a) { Console .WriteLine (i); }
4、注意事项
借助foreach,只能一一取得数组中的元素,并不能利用这种语句改变数组所存储的元素。
while类
1、使用方法
while(条件) { 循环体 }
只要条件为真,就执行循环体
switch类
1、使用方法
switch(expression){ case 条件 : 语句; break; case 条件 : 语句; break; /* 您可以有任意数量的 case 语句 */ default : /* 可选的 */ 语句; break; }
2、
switch 语句必须遵循下面的规则:
- switch 语句中的 expression 必须是一个整型或枚举类型,或者是一个 class 类型,其中 class 有一个单一的转换函数将其转换为整型或枚举类型。
- 在一个 switch 中可以有任意数量的 case 语句。每个 case 后跟一个要比较的值和一个冒号。
- case 的 constant-expression 必须与 switch 中的变量具有相同的数据类型,且必须是一个常量。
- 当被测试的变量等于 case 中的常量时,case 后跟的语句将被执行,直到遇到 break 语句为止。
- 当遇到 break 语句时,switch 终止,控制流将跳转到 switch 语句后的下一行。
- 不是每一个 case 都需要包含 break。如果 case 语句为空,则可以不包含 break,控制流将会 继续 后续的 case,直到遇到 break 为止。
- C# 不允许从一个开关部分继续执行到下一个开关部分。如果 case 语句中有处理语句,则必须包含 break 或其他跳转语句。
- 一个 switch 语句可以有一个可选的 default case,出现在 switch 的结尾。default case 可用于在上面所有 case 都不为真时执行一个任务。default case 中的 break 语句不是必需的。
- C# 不支持从一个 case 标签显式贯穿到另一个 case 标签。如果要使 C# 支持从一个 case 标签显式贯穿到另一个 case 标签,可以使用 goto 一个 switch-case 或 goto default。
3、例子
using System; namespace DecisionMaking { class Program { static void Main(string[] args) { /* 局部变量定义 */ char grade = 'B'; switch (grade) { case 'A': Console.WriteLine("很棒!"); break; case 'B': case 'C': Console.WriteLine("做得好"); break; case 'D': Console.WriteLine("您通过了"); break; case 'F': Console.WriteLine("最好再试一下"); break; default: Console.WriteLine("无效的成绩"); break; } Console.WriteLine("您的成绩是 {0}", grade); Console.ReadLine(); } } }
usingSystem;namespaceDecisionMaking{classProgram{staticvoidMain(string[] args){/* 局部变量定义 */char grade ='B';switch(grade){case'A':Console.WriteLine("很棒!");break;case'B':case'C':Console.WriteLine("做得好");break;case'D':Console.WriteLine("您通过了");break;case'F':Console.WriteLine("最好再试一下");break;default:Console.WriteLine("无效的成绩");break;}Console.WriteLine("您的成绩是 {0}", grade);Console.ReadLine();}}}