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>
可能是更好的选择。