C#类型转换和集合类型

目录

1.字符串和整型之间的转换

1.1字符串转化为整型:

1.2整型转化为字符串 

2.获字符串和日期之间的转换

2.1获取当前日期

2.2字符串转日期

2.3日期转字符串

2.4提取日期中的年月日等信息

3.举例一维、二维、三维数组

3.1一维数组 

3.2二维数组

3.3三维数组 

4.需求:有个88笔费用记录,总额3亿,金额在300万~800万之间,随机数如何实现?并记录总耗时。

5.常见的集合类型的存储结构和它们的作用以及优缺点

5.1静态数组 (Array)

5.2动态数组 ArrayList

5.3动态数组 List

5.4链表 LinkedList

5.5队列Queue

5.6栈Stack


1.字符串和整型之间的转换

1.1字符串转化为整型:

        一种是使用Parse()方法,int.Parse()方法在无法解析字符串时会直接抛出FormatException。

string str = "123";
int a = int.Parse(str);
Console.WriteLine(a);

        一种是Convert.ToInt32()方法,Convert.ToInt32()方法尝试将字符串的参数转换为32位有符号整数。如果字符串不能转换为整数,则会抛出FormatException或OverflowException。

int b = Convert.ToInt32(str);
Console.WriteLine(b);

        还有一种 int.TryParse()方法,如果你不确定字符串是否一定可以转换为整数,那么使用int.TryParse()方法是一个更好的选择。这个方法尝试将字符串的参数转换为整数,并返回一个布尔值以指示转换是否成功。如果转换成功,out参数将包含转换后的整数。


if (int.TryParse(str, out int number))  
{  
    Console.WriteLine(number); // 输出: 123  
}  
else  
{  
    Console.WriteLine("转换失败");  
}
1.2整型转化为字符串:

        一种方法是ToString()方法 ,对于任何整数类型(如int、long等),都可以直接调用其ToString()方法将其转换为字符串。

        一种方法是可以直接和空串进行相加,任何类型和字符串连接结果都是字符串。

int n = 123;
//第一种方式
Console.WriteLine(Convert.ToString(n));
//第二种方式
Console.WriteLine(""+n);


2.获字符串和日期之间的转换

2.1获取当前日期

        使用datetime模块的datetime.now()方法,可以获取当前的日期和时间。

DateTime currentTime = DateTime.Now;
2.2字符串转日期

        可以使用Parse()或方法。

string s = "2024-07-04";
DateTime date = DateTime.Parse(s);
Console.WriteLine(date);
2.3日期转字符串

         使用ToString()方法

DateTime now = DateTime.Now;  
  
// 使用默认的格式(依赖于当前的文化设置)  
string defaultString = now.ToString();  
  
// 使用自定义的格式  
string customString = now.ToString("yyyy-MM-dd HH:mm:ss");  
  
Console.WriteLine("默认格式: " + defaultString);  
Console.WriteLine("自定义格式: " + customString);
2.4提取日期中的年月日等信息
DateTime dt = new DateTime(2024, 7, 4, 9, 51, 09);
Console.WriteLine(dt.ToString());
Console.WriteLine(dt.Year.ToString());
Console.WriteLine(dt.Month.ToString());
Console.WriteLine(dt.Day.ToString());


3.举例一维、二维、三维数组

        在C#中,数组是一种数据结构,用于在计算机内存中连续存储相同类型的数据项。数组中的每个元素都可以通过索引来访问,索引通常是一个整数,表示元素在数组中的位置。数组的大小在声明时必须指定,并且之后不能更改。

3.1一维数组 

 一维数组有三种创建形式:

//三种方式
int[] a1 = new int[3];
int[] a2 = new int[3] { 1, 2, 3 };
int[] a3 = { 1, 2, 3 };
//若是不进行赋值,初始化值都为0

 产生长度固定的随机数组:

int[] a4 = new int[10];
Random rd = new Random();
for (int i = 0; i < a4.Length; i++)
{
    a4[i] = rd.Next(1, 101);//左闭右开
}
for (int i = 0; i < a4.Length; i++)
{
    Console.Write(a4[i] + " ");
}
3.2二维数组

        二维数组可以看作是一个表格,它有两个维度:行和列。每个元素可以通过行索引和列索引来访问。

//创建一个二维数组
int[,] a2 = new int[2,3];//声明一个两行三列的二维数组
int[,] a2 = new int[2, 3] { { 1, 2, 3 }, { 4, 5, 6 } };

 遍历二维数组:GetLength()方法,getlength获取维度长度而不是数组长度,维度从0开始

for (int i = 0; i < a2.GetLength(0); i++)
{
    for (int j = 0; j < a2.GetLength(1); j++)
    {
        Console.Write(a2[i, j] + " ");
    }
    Console.WriteLine();
}
3.3三维数组 

        三维数组可以想象成是由多个二维数组(即多个表格)堆叠而成的结构,它有三个维度:深度、行和列。

int[,,] a3 = new int[2, 2, 2] { { { 1, 2 }, { 3, 4 } }, { { 5, 6 }, { 7, 8 } } };
a3[0, 0, 0] = 100;
a3[1, 1, 1] = 999;
for (int i = 0; i < a3.GetLength(0); i++)
{
    for (int j = 0; j < a3.GetLength(1); j++)
    {
        for (int k = 0; k < a3.GetLength(2); k++)
        {
            Console.Write(a3[i, j, k] + " ");
        }
        Console.WriteLine();
    }
    Console.WriteLine();
}


4.需求:有个88笔费用记录,总额3亿,金额在300万~800万之间,随机数如何实现?并记录总耗时。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        int totalRecords = 88;
        decimal totalAmountNeeded = 300000000m; // 3亿  
        decimal minAmount = 3000000m; // 300万  
        decimal maxAmount = 8000000m; // 800万  
        Stopwatch stopwatch = Stopwatch.StartNew();
        Random random = new Random();
        List<decimal> expenses = new List<decimal>(); // 使用List以动态管理大小  
        decimal currentTotal = 0m;

        decimal average = (decimal)Math.Ceiling(totalAmountNeeded / totalRecords); // 使用Ceiling确保平均金额向上取整  

        for (int i = 0; i < totalRecords; i++)
        {
            // 允许一定的波动,但不超过平均金额的10%  
            decimal fluctuation = (decimal)random.NextDouble() * (average / 10);
            fluctuation -= average / 20; // 使波动范围在-10%到+10%之间  

            decimal amount = average + fluctuation;

            // 确保金额在合理范围内  
            amount = Math.Max(minAmount, Math.Min(amount, maxAmount));

            expenses.Add(amount); // 将金额添加到列表中  
            currentTotal += amount;

        }

        // 打印结果  
        foreach (var expense in expenses)
        {
            Console.WriteLine(expense.ToString("N0"));
        }

        Console.WriteLine($"总金额: {currentTotal.ToString("N0")}");
        // 输出总耗时  
        Console.WriteLine($"总耗时: {stopwatch.ElapsedMilliseconds} 毫秒");
    }
}

 输出结果:


5.常见的集合类型的存储结构和它们的作用以及优缺点

常见的集合类型有以下几种: 

5.1静态数组 (Array)

存储结构:固定大小的连续内存块。

作用:存储固定数量的相同类型的数据项。

优点

  • 访问速度快(通过索引直接访问)。
  • 占用内存少(因为是连续存储)。

缺点

  • 大小固定,不能动态增加或减少元素。
int[] a1 = { 1, 2, 3, 4, 5 };//静态数组,一旦分配完空间内存空间不允许改变
a1[5] = 5;//超过数组范围
5.2动态数组 ArrayList

存储结构:内部使用数组,但能够动态调整大小。

作用:提供动态调整大小的数组功能,但不是类型安全的。

优点

  • 动态扩容。
  • 可以存储任意类型的对象。

缺点

  • 不是类型安全的,存在装箱和拆箱的开销。
  • 性能通常不如List<T>。
using System.Collections;
ArrayList arrayList = new ArrayList();
//添加元素
arrayList.Add(100);
arrayList.Add(400);
arrayList.Add(300);
arrayList.Add(400);
arrayList.Add(500);//超过内存申请的空间,自动扩容(扩容策略:翻倍)
Console.WriteLine("动态数组的容量:{0}", arrayList.Capacity);
Console.WriteLine("动态数组的元素个数:{0}", arrayList.Count);
//删除元素
arrayList.Remove(500);//直接删除
arrayList.RemoveAt(0);//按索引删除
Console.WriteLine("动态数组的容量:{0}", arrayList.Capacity);
Console.WriteLine("动态数组的元素个数:{0}", arrayList.Count);
arrayList.Sort();//排序
arrayList.Clear();//清空
foreach (int item in arrayList)
{
    Console.WriteLine(item);
}
5.3动态数组 List<T>

存储结构:内部使用数组,但能够动态调整大小,并且是类型安全的。

作用:提供类型安全的动态数组功能。

优点

  • 动态扩容。
  • 类型安全,无需装箱和拆箱。
  • 提供丰富的功能,如排序、搜索等。

缺点

  • 在列表中间插入或删除元素时可能需要移动大量元素,影响性能。
using System.Collections;
ArrayList arrayList = new ArrayList();
arrayList.Add(100);
arrayList.Add("200");
Console.WriteLine("执行正常");
foreach (var i in arrayList)
{
    Console.WriteLine(i);
}
//泛型,编译器编译时可以进行类型检查
List<int> list = new List<int>();
list.Add(100);
list.Add(200);
list.Add(300);
list.Add(400);
//list.Add("200");//泛型在编译时就进行类型检查,防止运行时报错
Console.WriteLine("容量:" + list.Capacity);
Console.WriteLine("个数:" + list.Count);
list.Remove(200);
list.RemoveAt(1);
list.Sort();
foreach (int i in list)
{
    Console.WriteLine(i);
}
5.4链表 LinkedList<T>

存储结构:由一系列节点组成,每个节点包含数据和指向下一个节点的链接。

作用:提供在任意位置高效插入和删除元素的能力。

优点

  • 在链表中间插入或删除元素时性能高(不需要移动其他元素)。

缺点

  • 随机访问速度慢(需要从头或尾遍历)。
  • 占用内存可能比动态数组多(因为每个节点都需要额外的存储空间来存储链接)。
LinkedList<string> linkedList = new LinkedList<string>();
linkedList.AddFirst("陈晨");
linkedList.AddFirst("陈希");
linkedList.AddFirst("陈冲");
linkedList.AddLast("陈川");
linkedList.Remove("陈晨");
linkedList.Remove("陈晨");
var node = linkedList.Find("陈冲");
Console.WriteLine("当前节点的值:" + node.Value);
foreach (string linked in linkedList)
{
    Console.WriteLine(linked);
}

        linkedList.AddFirst和 linkedList.AddLast是.NET中LinkedList<T>类提供的两个方法,它们的主要区别在于向链表中添加元素时的位置不同。

  • linkedList.AddFirst(T value):这个方法用于在链表的开头(即头部)添加一个新的元素。如果链表是空的,那么这个新元素将成为链表中唯一的元素。如果链表已经包含元素,新元素将被添加到链表的第一个元素之前,成为新的第一个元素。
  • linkedList.AddLast(T value):这个方法用于在链表的末尾(即尾部)添加一个新的元素。如果链表是空的,那么这个新元素同样会成为链表中唯一的元素。如果链表已经包含元素,新元素将被添加到链表的最后一个元素之后,成为新的最后一个元素。

 这两个方法都接受一个类型为T的参数value,其中T是LinkedList<T>中元素的类型。它们都会使链表的Count属性增加1,但添加元素的位置不同。

5.5队列Queue<T>

存储结构

  • 队列是一种先进先出(FIFO)的数据结构。在内部,它通常使用数组或链表来实现,但具体实现是.NET Framework的内部细节,用户不需要关心。

作用

  • 用于存储元素的集合,但元素的添加(入队)是在集合的一端进行,而元素的移除(出队)则是在另一端进行。这种特性使得队列非常适合于处理一系列需要按顺序处理的元素。

优点

  • 提供了高效的元素入队和出队操作。
  • 元素的顺序性保证了数据处理的顺序。

缺点

  • 如果需要频繁地在队列中间进行插入或删除操作,则性能可能不佳。
using System;  
using System.Collections.Generic;  
  
class Program  
{  
    static void Main()  
    {  
        Queue<int> queue = new Queue<int>();  
  
        // 入队  
        queue.Enqueue(1);  
        queue.Enqueue(2);  
        queue.Enqueue(3);  
  
        // 遍历队列  
        foreach (var item in queue)  
        {  
            Console.WriteLine(item);  
        }  
  
        // 出队  
        Console.WriteLine("出队元素: " + queue.Dequeue());  
  
        // 再次遍历队列  
        Console.WriteLine("剩余队列:");  
        foreach (var item in queue)  
        {  
            Console.WriteLine(item);  
        }  
    }  
}
5.6栈Stack<T>

存储结构

  • 栈是一种后进先出(LIFO)的数据结构。同样,它的内部实现可能是数组或链表,但这对于用户来说是透明的。

作用

  • 用于存储元素的集合,但元素的添加(入栈)和移除(出栈)都在集合的同一端进行。这种特性使得栈非常适合于处理需要后进先出顺序处理的元素。

优点

  • 提供了高效的元素入栈和出栈操作。
  • 元素的顺序性使得栈成为递归和函数调用栈等场景的理想选择。

缺点

  • 如果需要频繁地在栈中间进行插入或删除操作,则性能可能不佳。
  • 访问栈中的非顶部元素可能比较耗时。
using System;  
using System.Collections.Generic;  
  
class Program  
{  
    static void Main()  
    {  
        Stack<int> stack = new Stack<int>();  
  
        // 入栈  
        stack.Push(1);  
        stack.Push(2);  
        stack.Push(3);  
  
        // 遍历栈 
        Array.ForEach(stack.ToArray(), item => Console.WriteLine(item));  
  
        // 出栈  
        Console.WriteLine("出栈元素: " + stack.Pop());  
  
        // 再次遍历栈 
        Console.WriteLine("剩余栈:");  
        Array.ForEach(stack.ToArray(), item => Console.WriteLine(item));  
    }  
}

  • 20
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值