csharp:第四章数组与集合
目录
第四章 数组与集合
4.1 数组
数组基础
数组是固定大小的、相同类型元素的连续集合。
// 声明和初始化 int[] numbers = new int[5]; // 声明长度为5的数组 int[] scores = { 85, 90, 78, 92, 88 }; // 声明并初始化 string[] names = new string[] { "Alice", "Bob", "Charlie" }; // 访问元素 Console.WriteLine(scores[0]); // 85 scores[1] = 95; // 修改元素 // 数组长度 Console.WriteLine(scores.Length); // 5
多维数组
// 二维数组 int[,] matrix = new int[3, 4]; int[,] table = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } }; // 访问 Console.WriteLine(table[0, 0]); // 1 Console.WriteLine(table[1, 2]); // 6 // 获取维度长度 Console.WriteLine(table.GetLength(0)); // 3行 Console.WriteLine(table.GetLength(1)); // 3列 // 遍历 for (int i = 0; i < table.GetLength(0); i++) { for (int j = 0; j < table.GetLength(1); j++) { Console.Write($"{table[i, j]} "); } Console.WriteLine(); }
交错数组
// 交错数组(数组的数组) int[][] jagged = new int[3][]; jagged[0] = new int[] { 1, 2 }; jagged[1] = new int[] { 3, 4, 5 }; jagged[2] = new int[] { 6 }; // 初始化语法 int[][] jagged2 = new int[][] { new int[] { 1, 2 }, new int[] { 3, 4, 5, 6 }, new int[] { 7, 8, 9 } }; // 遍历 foreach (int[] row in jagged) { foreach (int num in row) { Console.Write(num + " "); } Console.WriteLine(); }
数组方法
int[] arr = { 3, 1, 4, 1, 5, 9, 2, 6 }; // 排序 Array.Sort(arr); // [1, 1, 2, 3, 4, 5, 6, 9] // 反转 Array.Reverse(arr); // [9, 6, 5, 4, 3, 2, 1, 1] // 查找 int index = Array.IndexOf(arr, 5); // 返回5的索引 int lastIndex = Array.LastIndexOf(arr, 1); // 二分查找(数组必须先排序) int found = Array.BinarySearch(arr, 5); // 清空 Array.Clear(arr, 0, 3); // 将前3个元素设为0 // 复制 int[] copy = new int[arr.Length]; Array.Copy(arr, copy, arr.Length); int[] clone = (int[])arr.Clone();
4.2 ArrayList与List<T>
ArrayList(非泛型)
using System.Collections; ArrayList list = new ArrayList(); list.Add(1); // 添加整数 list.Add("Hello"); // 添加字符串 list.Add(3.14); // 添加浮点数 // 缺点:需要装箱拆箱,类型不安全 int num = (int)list[0]; // 需要强制转换
List<T>(泛型,推荐使用)
using System.Collections.Generic; // 创建List List<int> numbers = new List<int>(); List<string> names = new List<string> { "Alice", "Bob", "Charlie" }; // 添加元素 numbers.Add(10); numbers.AddRange(new[] { 20, 30, 40 }); // 插入 numbers.Insert(0, 5); // 在索引0处插入5 // 删除 numbers.Remove(10); // 删除第一个值为10的元素 numbers.RemoveAt(0); // 删除索引0的元素 numbers.RemoveAll(x => x > 25); // 删除所有大于25的元素 // 查找 bool contains = numbers.Contains(20); int index = numbers.IndexOf(20); int foundIndex = numbers.FindIndex(x => x > 15); int found = numbers.Find(x => x > 15); // 排序和反转 numbers.Sort(); numbers.Sort((a, b) => b.CompareTo(a)); // 降序排序 numbers.Reverse(); // 其他操作 numbers.Clear(); int count = numbers.Count; int capacity = numbers.Capacity;
4.3 Dictionary<K,V>
// 创建字典 Dictionary<string, int> ages = new Dictionary<string, int>(); Dictionary<string, string> capitals = new Dictionary<string, string> { { "中国", "北京" }, { "美国", "华盛顿" }, { "日本", "东京" } }; // 添加 ages.Add("Alice", 25); ages["Bob"] = 30; // 添加或更新 // 安全添加 if (!ages.ContainsKey("Charlie")) { ages.Add("Charlie", 35); } // 访问 int aliceAge = ages["Alice"]; // 安全访问 if (ages.TryGetValue("Alice", out int age)) { Console.WriteLine($"Alice的年龄: {age}"); } // 遍历 foreach (var pair in capitals) { Console.WriteLine($"{pair.Key}: {pair.Value}"); } foreach (string key in capitals.Keys) { Console.WriteLine(key); } foreach (string value in capitals.Values) { Console.WriteLine(value); } // 删除 ages.Remove("Alice"); ages.Clear();
4.4 其他常用集合
HashSet<T>
// 集合:无序、不重复 HashSet<int> set = new HashSet<int>(); set.Add(1); set.Add(2); set.Add(1); // 重复,不会添加 Console.WriteLine(set.Count); // 2 // 集合运算 HashSet<int> set1 = new HashSet<int> { 1, 2, 3, 4 }; HashSet<int> set2 = new HashSet<int> { 3, 4, 5, 6 }; set1.IntersectWith(set2); // 交集: {3, 4} set1.UnionWith(set2); // 并集 set1.ExceptWith(set2); // 差集 set1.SymmetricExceptWith(set2); // 对称差集
Queue<T>
// 队列:先进先出(FIFO) Queue<string> queue = new Queue<string>(); queue.Enqueue("First"); // 入队 queue.Enqueue("Second"); queue.Enqueue("Third"); string first = queue.Dequeue(); // 出队: "First" string peek = queue.Peek(); // 查看队首但不移除: "Second" int count = queue.Count;
Stack<T>
// 栈:后进先出(LIFO) Stack<string> stack = new Stack<string>(); stack.Push("First"); // 压栈 stack.Push("Second"); stack.Push("Third"); string top = stack.Pop(); // 出栈: "Third" string peek = stack.Peek(); // 查看栈顶: "Second" int count = stack.Count;
SortedList<TKey, TValue>
// 按键排序的字典 SortedList<string, int> sortedList = new SortedList<string, int>(); sortedList.Add("Charlie", 3); sortedList.Add("Alice", 1); sortedList.Add("Bob", 2); // 遍历时按键排序 foreach (var pair in sortedList) { Console.WriteLine($"{pair.Key}: {pair.Value}"); } // 输出: Alice, Bob, Charlie
4.5 LINQ基础
LINQ简介
LINQ(Language Integrated Query)是集成在C#中的查询语言。
using System.Linq; int[] numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
查询语法
// 查询语法 var evenNumbers = from n in numbers where n % 2 == 0 select n; // 排序 var sorted = from n in numbers orderby n descending select n; // 多条件 var result = from n in numbers where n > 3 && n < 8 orderby n select n;
方法语法
// Where过滤 var evenNumbers = numbers.Where(n => n % 2 == 0); // Select投影 var squares = numbers.Select(n => n * n); // 排序 var sorted = numbers.OrderBy(n => n); var sortedDesc = numbers.OrderByDescending(n => n); // 多级排序 var students = new[] { new { Name = "Alice", Grade = 90, Class = "A" }, new { Name = "Bob", Grade = 85, Class = "B" }, new { Name = "Charlie", Grade = 90, Class = "A" } }; var ordered = students .OrderBy(s => s.Class) .ThenByDescending(s => s.Grade);
常用LINQ操作
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; // 聚合 int sum = nums.Sum(); double avg = nums.Average(); int max = nums.Max(); int min = nums.Min(); int count = nums.Count(); int countEven = nums.Count(n => n % 2 == 0); // 量化 bool hasAny = nums.Any(); bool hasEven = nums.Any(n => n % 2 == 0); bool allPositive = nums.All(n => n > 0); bool containsFive = nums.Contains(5); // 分区 var first3 = nums.Take(3); // 前3个 var skip3 = nums.Skip(3); // 跳过前3个 var takeWhile = nums.TakeWhile(n => n < 5); // 去重 var distinct = new[] { 1, 2, 2, 3, 3, 3 }.Distinct(); // 转换 List<int> list = nums.ToList(); int[] array = list.ToArray(); Dictionary<int, int> dict = nums.ToDictionary(n => n, n => n * n);
4.6 Span<T>和Memory<T>(C# 7.2+)
// Span<T>: 安全的内存切片,栈上分配 void ProcessSpan() { int[] arr = { 1, 2, 3, 4, 5 }; Span<int> span = arr; // 整个数组 Span<int> slice = arr.AsSpan(1, 3); // 切片 [2, 3, 4] span[0] = 100; // 修改会影响原数组 // 栈上分配的Span Span<int> stackSpan = stackalloc int[10]; } // Memory<T>: 堆上分配,可用于异步操作 async Task ProcessMemoryAsync() { byte[] data = await File.ReadAllBytesAsync("file.txt"); Memory<byte> memory = data; Memory<byte> slice = memory.Slice(10, 100); }
4.7 集合初始化器
// 集合初始化器 var list = new List<int> { 1, 2, 3, 4, 5 }; var dict = new Dictionary<string, int> { ["one"] = 1, ["two"] = 2, ["three"] = 3 }; // 对象集合 var people = new List<Person> { new Person { Name = "Alice", Age = 25 }, new Person { Name = "Bob", Age = 30 } }; // C# 6+ 索引初始化器 var numbers = new Dictionary<int, string> { [1] = "one", [2] = "two", [3] = "three" };
练习题
基础练习
1. 数组操作:创建一个整数数组,实现以下功能:
- 找出最大值和最小值
- 计算平均值
- 找出第二大的数
- 将数组按升序排序后反转
2. 矩阵运算:编写方法实现两个二维矩阵的加法和乘法。
3. List操作:创建一个字符串List,完成以下操作:
- 添加10个名字
- 删除所有以“A”开头的名字
- 按字母顺序排序
- 查找包含字母“e”的所有名字
进阶练习
4. 学生成绩系统:使用Dictionary存储学生姓名和成绩,实现:
- 添加学生成绩
- 查询学生成绩
- 计算班级平均分
- 找出最高分和最低分的学生
- 按成绩排序输出
5. 集合运算:给定两个整数数组,找出:
- 同时存在于两个数组中的元素(交集)
- 只存在于第一个数组中的元素(差集)
- 存在于任一数组中的所有不同元素(并集)
6. 队列实现:使用Queue实现一个任务调度器,支持:
- 添加任务
- 执行任务(出队)
- 查看待处理任务数
- 清空所有任务
挑战练习
7. LINQ综合应用:给定一个Product类(Id, Name, Category, Price),使用LINQ实现:
- 按类别分组统计数量和平均价格
- 找出每个类别中最贵的产品
- 筛选价格高于平均价的产品
- 实现分页查询
8. 自定义集合:实现一个简单的泛型集合类MyList<T>,支持:
- 添加元素
- 索引访问
- 枚举器(实现IEnumerable<T>)
- 自动扩容
9. 数据统计:使用数组或List存储一组实验数据,实现:
- 计算均值、中位数、众数
- 计算方差和标准差
- 找出异常值(超过3倍标准差的数据点)
本章小结
本章学习了C#的数组和集合:
- 一维数组、多维数组和交错数组
- Array类的方法和操作
- 泛型集合List<T>、Dictionary<K,V>
- 专用集合HashSet、Queue、Stack
- LINQ的基础查询语法和方法语法
- Span<T>和Memory<T>的高效内存操作
选择合适的集合类型对于程序性能至关重要。
csharp/第四章数组与集合.txt · 最后更改: 由 127.0.0.1
