1. 整数转换,整数和字符串,字符串和整数之间的转换怎么实现?
整数转字符串:
ToString()
方法来完成这个转换int number = 123; string strNumber = number.ToString(); Console.WriteLine(strNumber);
此外,
ToString()
方法允许你指定格式字符串,这样你就可以控制输出的格式。例如,如果你想以十六进制形式显示整数,你可以这样做:int number = 255; string hexString = number.ToString("X"); // X代表十六进制 Console.WriteLine(hexString); // 输出: FF
另一个常见的格式化字符串是"N0",它用于显示带有千位分隔符的数字:
int number = 123456789; string numberWithCommas = number.ToString("N0"); Console.WriteLine(numberWithCommas); // 输出: 123,456,789
如果你想要更高级的格式化,比如固定小数点后的位数,你可以使用类似"F2"这样的格式字符串,其中2表示小数点后两位:
double number = 123.456789; string formattedNumber = number.ToString("F2"); Console.WriteLine(formattedNumber); // 输出: 123.46
请注意,虽然最后一个例子使用的是
double
类型,但ToString()
方法同样适用于整数类型。如果你需要将整数转换为字符串,只需使用int
、long
或其他整数类型即可。字符串转整数:
在C#中,将字符串转换为整数可以通过多种方法实现,其中最常见的是使用
int.Parse()
和int.TryParse()
方法。使用
int.Parse()
int.Parse()
方法将字符串转换为32位有符号整数。如果字符串不能被解析为一个有效的整数,该方法将抛出一个FormatException
。string strNumber = "12345"; int number = int.Parse(strNumber); Console.WriteLine(number); // 输出: 12345
使用
int.TryParse()
int.TryParse()
方法也是将字符串转换为整数,但它不会抛出异常。相反,它返回一个布尔值,指示转换是否成功。如果转换成功,它通过out
参数返回转换后的整数值;如果转换失败,out
参数将被设置为int
类型的默认值(通常是0)。string strNumber = "12345"; int number; bool success = int.TryParse(strNumber, out number); if (success) { Console.WriteLine(number); // 输出: 12345 } else { Console.WriteLine("转换失败"); }
其他转换方法
除了
int.Parse()
和int.TryParse()
之外,还可以使用Convert.ToInt32()
方法,它提供了额外的转换选项,如指定基数(例如,二进制、八进制或十六进制)。string hexNumber = "1A"; int number = Convert.ToInt32(hexNumber, 16); Console.WriteLine(number); // 输出: 26
总结
在实际应用中,推荐使用
int.TryParse()
方法,因为它可以避免因无效输入而导致的异常,使代码更加健壮。如果输入的字符串可能不符合预期的格式,使用TryParse()
可以让你更优雅地处理错误情况。
2. 日期转换,获取当前日期,字符串转日期,日期转字符串怎么实现?
获取当前日期和时间
你可以使用
DateTime.Now
或DateTime.UtcNow
来获取本地或UTC的当前日期和时间。DateTime localNow = DateTime.Now; DateTime utcNow = DateTime.UtcNow;
日期转字符串
要将日期转换为字符串,你可以使用
ToString()
方法,并传入一个格式字符串来指定你想要的格式。DateTime someDate = new DateTime(2023, 1, 1); string dateString = someDate.ToString("yyyy-MM-dd"); Console.WriteLine(dateString); // 输出: 2023-01-01 DateTime dt2 = new DateTime(2024,1,1,9,51,09); Console.WriteLine(dt2.ToString()); Console.WriteLine(dt2.Year.ToString()); Console.WriteLine(dt2.Month.ToString()); Console.WriteLine(dt2.Day.ToString());
常见的格式化模式包括:
"yyyy-MM-dd"
: 四位年-两位月-两位日"dd/MM/yyyy"
: 两位日/两位月/四位年"HH:mm:ss"
: 24小时制的小时:分钟:秒"hh:mm:ss tt"
: 12小时制的小时:分钟:秒 AM/PM字符串转日期
要将字符串转换为日期,你可以使用
DateTime.Parse()
或更安全的DateTime.TryParse()
方法。string dateString = "2023-01-01"; DateTime parsedDate; if (DateTime.TryParse(dateString, out parsedDate)) { Console.WriteLine(parsedDate); // 输出: 1/1/2023 12:00:00 上午 } else { Console.WriteLine("日期格式不正确"); 10}
如果字符串的日期格式不固定,或者有多种可能的格式,你可以使用
DateTime.TryParseExact()
,并提供所有可能的格式字符串。string dateString = "01/01/2023"; string[] formats = { "dd/MM/yyyy", "MM/dd/yyyy", "yyyy-MM-dd" }; if (DateTime.TryParseExact(dateString, formats, CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime parsedDate)) { Console.WriteLine(parsedDate); } else { Console.WriteLine("无法解析日期"); }
以上代码演示了如何在C#中处理日期和时间的转换,包括获取当前日期时间、日期格式化、以及从字符串解析日期。
3. 举例一维、二维、三维数组
一维数组
一维数组是最基础的数组形式,它相当于一个线性的数据列表。
// 定义一个一维整型数组 int[] oneDimensionalArray = new int[5]; // 初始化一维数组 oneDimensionalArray = new int[] { 1, 2, 3, 4, 5 }; // 或者在定义时初始化 int[] oneDimArray = { 10, 20, 30, 40, 50 };
二维数组
二维数组可以想象成一个表格,它具有行和列,可以看作是多个一维数组的集合。
// 定义一个二维整型数组 int[,] twoDimensionalArray = new int[3, 4]; // 初始化二维数组 twoDimensionalArray = new int[,]{ { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }; // 或者在定义时初始化 int[,] twoDimArray = { { 13, 14, 15, 16 }, { 17, 18, 19, 20 }, { 21, 22, 23, 24 } };
三维数组
三维数组可以看作是一个立方体,它有三个维度,通常用来表示三维空间中的数据。
// 定义一个三维整型数组 int[,,] threeDimensionalArray = new int[2, 3, 4]; // 初始化三维数组 threeDimensionalArray = new int[,,] { { { 1, 2, 3, 4 }, { 5, 6, 7, 8 }, { 9, 10, 11, 12 } }, { { 13, 14, 15, 16 }, { 17, 18, 19, 20 }, { 21, 22, 23, 24 } } }; // 或者在定义时初始化 int[,,] threeDimArray = { { { 25, 26, 27, 28 }, { 29, 30, 31, 32 }, { 33, 34, 35, 36 } }, { { 37, 38, 39, 40 }, { 41, 42, 43, 44 }, { 45, 46, 47, 48 } } };
注意,在初始化多维数组时,数组的维度必须匹配。例如,在二维数组中,每一行的列数必须相同;在三维数组中,每一层的行数和列数也必须相同。
4. 需求:有个88笔费用记录,总额3亿,金额在300万~800万之间,随机数如何实现?并记录总耗时。
// 引入System.Diagnostics命名空间,用于使用Stopwatch类 using System.Diagnostics; // 创建一个随机数生成器 Random rand = new Random(); // 创建一个计时器,用于记录生成随机数所花费的时间 Stopwatch stopwatch = new Stopwatch(); // 开始计时 stopwatch.Start(); // 初始化一个空的列表,用于存储生成的随机数(费用) List<int> fees = new List<int>(); // 设置总的金额 int totalAmount = 300000000; // 设置需要生成的随机数(费用)的数量 int count = 88; // 计算平均每个随机数(费用)应该大约是多少 // 注意:实际生成的数值由于随机性不会严格等于这个平均值 double averageAmount = (double)totalAmount / count; // 循环生成指定数量的随机数(费用) for (int i = 0; i < count; i++) { // 生成一个介于300万到800万之间的随机整数(包含上下限) // 注意:这里rand.Next()的上限参数是开区间,即8000001是不包含在内的 int amount = rand.Next(3000000, 8000000); // 将生成的随机数添加到列表中 fees.Add(amount); // 从总金额中减去本次生成的随机数 // 这是为了尽可能使生成的随机数总和接近3亿 // 但实际总和由于随机性可能不会恰好等于3亿 totalAmount -= amount; } // 停止计时 stopwatch.Stop(); // 输出整个生成随机数的过程所花费的时间,单位为秒 // 使用string interpolation(字符串插值)来方便地在字符串中嵌入变量值 Console.WriteLine($"Total time taken: {stopwatch.Elapsed.TotalSeconds} seconds");
5. 简述常见的集合类型的存储结构和它们的作用以及优缺点,并写出实现案例
1.
List<T>
- 存储结构:动态数组。
List<T>
在内部使用一个数组来存储元素,当数组满时,它会自动扩容。- 作用:适用于需要频繁访问和修改元素的场景。
- 优点:
- 提供了索引访问,查找元素速度快。
- 支持动态增长和缩减。
- 缺点:
- 插入和删除元素时,如果不在数组末尾,需要移动大量元素,效率较低。
- 实现案例:
List<int> numbers = new List<int>(); numbers.Add(1); numbers.Add(2); numbers.Insert(1, 3); // 插入慢 numbers.RemoveAt(0); // 删除中间元素慢 Console.WriteLine(numbers[1]); // 快速随机访问
2.
Array
- 存储结构:固定大小的数组。
- 作用:用于存储固定数量的同类型元素。
- 优点:
- 访问元素非常快。
- 内存占用相对较小。
- 缺点:
- 大小固定,一旦创建后无法改变。
- 实现案例:
int[] arr = new int[5] { 1, 2, 3, 4, 5 }; Console.WriteLine(arr[2]);
3.
HashSet<T>
- 存储结构:基于哈希表。
HashSet<T>
使用哈希函数将元素映射到桶中,桶中存储元素的引用。- 作用:用于存储不重复的元素,提供快速的查找和插入。
- 优点:
- 查找、插入和删除操作的平均时间复杂度为O(1)。
- 缺点:
- 不保持元素的插入顺序。
- 需要一个良好的哈希函数以减少冲突。
- 实现案例:
HashSet<int> uniqueNumbers = new HashSet<int>(); uniqueNumbers.Add(1); uniqueNumbers.Add(2); uniqueNumbers.Add(2); // 不会被添加 foreach (var num in uniqueNumbers) { Console.WriteLine(num); }
4.
Dictionary<TKey, TValue>
- 存储结构:基于哈希表的键值对集合。
- 作用:用于存储键值对,键是唯一的,用于快速查找对应的值。
- 优点:
- 查找、插入和删除操作的平均时间复杂度为O(1)。
- 缺点:
- 键必须是唯一的。
- 需要一个良好的哈希函数以减少冲突。
- 实现案例:
Dictionary<string, int> scores = new Dictionary<string, int>(); scores.Add("Alice", 90); scores["Bob"] = 80; if (scores.ContainsKey("Alice")) { Console.WriteLine(scores["Alice"]); }
5.
Queue<T>
- 存储结构:先进先出(FIFO)队列。
- 作用:用于处理需要按顺序处理的元素队列。
- 优点:
- 自动管理队列中的元素顺序。
- 缺点:
- 插入和删除操作的时间复杂度为O(1),但访问中间元素较慢。
- 实现案例:
Queue<string> messages = new Queue<string>(); messages.Enqueue("Hello"); messages.Enqueue("World"); Console.WriteLine(messages.Dequeue());
6.
Stack<T>
- 存储结构:后进先出(LIFO)栈。
- 作用:用于处理需要按后进先出顺序处理的元素堆栈。
- 优点:
- 自动管理栈中的元素顺序。
- 缺点:
- 只能访问栈顶元素,访问或修改其他元素较慢。
- 实现案例:
Stack<int> stack = new Stack<int>(); stack.Push(1); stack.Push(2); Console.WriteLine(stack.Pop());
7.LinkedList<T>
存储结构:双向链表,每个元素包含指向前后元素的链接。
作用:用于存储元素集合,提供高效的插入和删除操作。
优点:
- 插入和删除元素快,无需移动其他元素。
缺点:
- 随机访问效率低,需要遍历链表。
- 每个元素需要额外的存储空间用于链接。
LinkedList<int> myList = new LinkedList<int>(); LinkedListNode<int> node = myList.AddLast(1); myList.AddAfter(node, 2); int firstItem = myList.First.Value;
这些集合类型的选择取决于具体的应用场景和性能需求。例如,如果需要快速的随机访问,可以选择
Array
或List<T>
;如果需要快速查找,可以选择Dictionary<TKey, TValue>
或HashSet<T>
;如果需要在集合中频繁插入和删除元素,则LinkedList<T>
可能是更好的选择。