c# 容器笔记

c#与c++的相似容器

c#中和std::set 的用法相似的容器

在 C# 中,和 C++ 中的 std::set 用法相似的容器是 HashSet<T>SortedSet<T>。这两者都实现了集合的功能,但有一些不同的特点。

HashSet<T>

  • 无序集合:不保证元素的顺序。
  • 快速查找:基于哈希表,查找、添加和删除操作的平均时间复杂度为 O(1)。
  • 唯一性:不允许重复元素。
用法示例:
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        HashSet<int> hashSet = new HashSet<int>();

        // 添加元素
        hashSet.Add(1);
        hashSet.Add(2);
        hashSet.Add(3);

        // 尝试添加重复元素
        bool added = hashSet.Add(3); // added will be false because 3 is already in the set

        // 检查元素是否存在
        bool contains = hashSet.Contains(2); // contains will be true

        // 删除元素
        hashSet.Remove(2);

        // 遍历元素
        foreach (int item in hashSet)
        {
            Console.WriteLine(item);
        }
    }
}

SortedSet<T>

  • 有序集合:元素按排序顺序存储(默认按升序排列)。
  • 较慢查找:基于红黑树,查找、添加和删除操作的平均时间复杂度为 O(log n)。
  • 唯一性:不允许重复元素。
用法示例:
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        SortedSet<int> sortedSet = new SortedSet<int>();

        // 添加元素
        sortedSet.Add(3);
        sortedSet.Add(1);
        sortedSet.Add(2);

        // 尝试添加重复元素
        bool added = sortedSet.Add(2); // added will be false because 2 is already in the set

        // 检查元素是否存在
        bool contains = sortedSet.Contains(1); // contains will be true

        // 删除元素
        sortedSet.Remove(1);

        // 遍历元素
        foreach (int item in sortedSet)
        {
            Console.WriteLine(item); // 输出为 2, 3 因为集合是有序的
        }
    }
}

选择 HashSet<T> 还是 SortedSet<T>

  • 如果需要快速查找和不关心元素的顺序,选择 HashSet<T>
  • 如果需要元素按顺序存储和查找稍微慢一些也能接受,选择 SortedSet<T>

这两个集合类都实现了 ISet<T> 接口,因此在使用集合操作时有类似的 API。根据你的具体需求选择适合的集合类型。

c# 中与pari相似的容器

在 C# 中,与 C++ 中的 std::pair 类似的容器是 TupleKeyValuePair

Tuple

Tuple 是一个通用的数据结构,可以存储一组相关的值。以下是一个示例,展示如何使用 Tuple

using System;

class Program
{
    static void Main()
    {
        // 创建一个Tuple来存储两个相关的值
        Tuple<int, string> person = new Tuple<int, string>(1, "John Doe");

        // 访问Tuple的元素
        int id = person.Item1;
        string name = person.Item2;

        Console.WriteLine($"ID: {id}, Name: {name}");
    }
}

KeyValuePair

KeyValuePair 是一种特定类型的容器,常用于字典(Dictionary)中来存储键值对。以下是一个示例,展示如何使用 KeyValuePair

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 创建一个Dictionary来存储键值对
        Dictionary<int, string> people = new Dictionary<int, string>();

        // 添加键值对到Dictionary中
        people.Add(1, "John Doe");
        people.Add(2, "Jane Doe");

        // 访问Dictionary中的元素
        foreach (KeyValuePair<int, string> person in people)
        {
            Console.WriteLine($"ID: {person.Key}, Name: {person.Value}");
        }
    }
}

使用 KeyValuePair 单独创建键值对

你也可以单独创建 KeyValuePair 对象,而不使用 Dictionary

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 创建一个KeyValuePair来存储两个相关的值
        KeyValuePair<int, string> person = new KeyValuePair<int, string>(1, "John Doe");

        // 访问KeyValuePair的元素
        int id = person.Key;
        string name = person.Value;

        Console.WriteLine($"ID: {id}, Name: {name}");
    }
}

比较 Tuple 和 KeyValuePair

  • Tuple 可以包含多个值(不仅限于两个),可以创建 Tuple<T1, T2, T3, ...>
  • KeyValuePair 是一种特定的容器,通常用于字典数据结构,具有明确的键和值。

根据你的具体需求,选择合适的数据结构。如果你需要存储一对值,并且它们是键值对关系,KeyValuePair 是一个不错的选择。如果你需要存储多于两个的相关值,Tuple 会更合适。

c# List 求最大值
在 C# 中,可以使用 List<T> 来存储一系列元素,并通过多种方式来求取最大值。最常用的方法是使用 LINQ 提供的 Max 方法。以下是几种常见的求最大值的方法:

使用 LINQ 的 Max 方法

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

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 5, 10, 3, 8, 15 };

        // 使用 LINQ 的 Max 方法
        int maxNumber = numbers.Max();

        Console.WriteLine($"The maximum number is {maxNumber}");
    }
}

使用循环求最大值

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 5, 10, 3, 8, 15 };

        // 使用循环求最大值
        int maxNumber = int.MinValue;
        foreach (int number in numbers)
        {
            if (number > maxNumber)
            {
                maxNumber = number;
            }
        }

        Console.WriteLine($"The maximum number is {maxNumber}");
    }
}

使用 IComparer<T>List<T>.Sort 方法

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 5, 10, 3, 8, 15 };

        // 使用 IComparer<T> 和 List<T>.Sort 方法
        numbers.Sort();
        int maxNumber = numbers[numbers.Count - 1];

        Console.WriteLine($"The maximum number is {maxNumber}");
    }
}

求取对象列表中的最大值

如果你有一个包含对象的列表,并且想根据对象的某个属性求最大值,可以使用 LINQMax 方法并传递一个选择器。

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

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

class Program
{
    static void Main()
    {
        List<Person> people = new List<Person>
        {
            new Person { Name = "Alice", Age = 30 },
            new Person { Name = "Bob", Age = 25 },
            new Person { Name = "Charlie", Age = 35 }
        };

        // 使用 LINQ 的 Max 方法求最大年龄
        int maxAge = people.Max(p => p.Age);

        Console.WriteLine($"The maximum age is {maxAge}");
    }
}

这些方法都能有效地求取 List<T> 中的最大值,根据具体需求选择合适的方法。一般情况下,使用 LINQMax 方法最为简洁和方便。

判断List是否为空

在 C# 中,可以通过多种方式来判断一个 List<T> 是否为空。以下是一些常见的方法:

使用 Count 属性

这是最直接的方法,通过检查 List<T>Count 属性来判断是否为空。

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int>();

        // 使用 Count 属性判断是否为空
        if (numbers.Count == 0)
        {
            Console.WriteLine("The list is empty.");
        }
        else
        {
            Console.WriteLine("The list is not empty.");
        }
    }
}

使用 Any 方法

LINQ 提供的 Any 方法也可以用来检查列表是否为空。Any 方法返回一个布尔值,指示是否存在任何元素。

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

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int>();

        // 使用 LINQ 的 Any 方法判断是否为空
        if (!numbers.Any())
        {
            Console.WriteLine("The list is empty.");
        }
        else
        {
            Console.WriteLine("The list is not empty.");
        }
    }
}

直接检查 List<T> 是否为 null

在实际应用中,还应该考虑列表本身是否为 null。在这种情况下,先判断列表是否为 null,再判断列表是否为空。

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

class Program
{
    static void Main()
    {
        List<int> numbers = null;

        // 检查列表是否为 null
        if (numbers == null)
        {
            Console.WriteLine("The list is null.");
        }
        else if (numbers.Count == 0)
        {
            Console.WriteLine("The list is empty.");
        }
        else
        {
            Console.WriteLine("The list is not empty.");
        }
    }
}

综合判断(处理 null 和空列表)

可以将判断 null 和空列表的逻辑合并为一个方法,方便重复使用:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = null;

        if (IsNullOrEmpty(numbers))
        {
            Console.WriteLine("The list is null or empty.");
        }
        else
        {
            Console.WriteLine("The list is not empty.");
        }
    }

    static bool IsNullOrEmpty<T>(List<T> list)
    {
        return list == null || list.Count == 0;
    }
}

这些方法都可以有效地判断 List<T> 是否为空。根据具体场景的需求选择合适的方法。一般情况下,使用 Count 属性或者 LINQAny 方法最为常见和简洁。如果需要同时处理 null 和空列表的情况,可以使用综合判断方法。

取List第一个元素

在 C# 中,可以通过多种方式获取 List<T> 的第一个元素。以下是一些常见的方法:

使用索引

这是最直接的方法,通过索引来访问 List<T> 的第一个元素。需要注意的是,在访问之前应该检查列表是否为空,以避免 IndexOutOfRangeException 异常。

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        if (numbers.Count > 0)
        {
            int firstElement = numbers[0];
            Console.WriteLine("The first element is: " + firstElement);
        }
        else
        {
            Console.WriteLine("The list is empty.");
        }
    }
}

使用 First 方法

LINQ 提供的 First 方法可以用于获取列表的第一个元素。需要导入 System.Linq 命名空间。First 方法在列表为空时会抛出 InvalidOperationException 异常,因此使用之前可以检查列表是否为空,或者使用 FirstOrDefault 方法。

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

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        if (numbers.Any())
        {
            int firstElement = numbers.First();
            Console.WriteLine("The first element is: " + firstElement);
        }
        else
        {
            Console.WriteLine("The list is empty.");
        }
    }
}

使用 FirstOrDefault 方法

FirstOrDefault 方法在列表为空时不会抛出异常,而是返回默认值。对于引用类型,默认值是 null;对于值类型,默认值是类型的默认值(例如 int 的默认值是 0)。

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

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        int firstElement = numbers.FirstOrDefault();
        if (numbers.Any())
        {
            Console.WriteLine("The first element is: " + firstElement);
        }
        else
        {
            Console.WriteLine("The list is empty.");
        }
    }
}

综合判断并获取第一个元素的方法

可以将判断列表是否为空和获取第一个元素的逻辑合并到一个方法中:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

        int? firstElement = GetFirstElement(numbers);
        if (firstElement.HasValue)
        {
            Console.WriteLine("The first element is: " + firstElement.Value);
        }
        else
        {
            Console.WriteLine("The list is empty.");
        }
    }

    static int? GetFirstElement(List<int> list)
    {
        if (list == null || list.Count == 0)
        {
            return null;
        }
        return list[0];
    }
}

在这个例子中,GetFirstElement 方法返回一个 Nullable<int>,即 int? 类型,以便处理空列表的情况。在调用该方法后,可以检查返回值是否有值(即 HasValue 属性),然后再使用值(通过 Value 属性)。

这些方法都可以有效地获取 List<T> 的第一个元素。根据具体的应用场景选择合适的方法。如果需要同时处理 null 和空列表的情况,可以使用综合判断的方法。

判断HashSet中是否有这个元素

在 C# 中,可以使用 HashSet<T>Contains 方法来判断集合中是否包含特定元素。HashSet<T> 是一个非常高效的数据结构,用于存储唯一值,并且其查找操作的平均时间复杂度为 O(1)。

下面是一个示例代码,展示如何在 HashSet<int> 中判断是否包含某个元素:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        // 创建一个HashSet并添加一些元素
        HashSet<int> numbers = new HashSet<int> { 1, 2, 3, 4, 5 };

        // 要查找的元素
        int elementToFind = 3;

        // 判断HashSet中是否包含该元素
        if (numbers.Contains(elementToFind))
        {
            Console.WriteLine($"HashSet contains the element {elementToFind}.");
        }
        else
        {
            Console.WriteLine($"HashSet does not contain the element {elementToFind}.");
        }
    }
}

在上面的示例中,我们首先创建了一个包含整数的 HashSet 并添加了一些元素。然后,我们使用 Contains 方法检查 HashSet 中是否存在指定的元素 elementToFind

解释

  • HashSet<int> numbers = new HashSet<int> { 1, 2, 3, 4, 5 };:创建一个 HashSet 并初始化一些整数元素。
  • int elementToFind = 3;:要查找的元素。
  • if (numbers.Contains(elementToFind)):使用 Contains 方法判断 HashSet 中是否包含 elementToFind
  • 如果包含,输出 “HashSet contains the element {elementToFind}.”。
  • 否则,输出 “HashSet does not contain the element {elementToFind}.”。

Contains 方法返回一个布尔值,指示 HashSet 是否包含指定的元素。这使得查找操作变得非常简单和高效。

tuple 求double 求出最小值对应的项

要在一个包含 Tuple<int, double>List 中找到 double 最小值对应的 Tuple<int, double> 项,可以使用 LINQ。这里是一个示例代码,演示如何实现这一点:

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

class Program
{
    static void Main()
    {
        // 创建一个包含 Tuple<int, double> 的列表
        List<Tuple<int, double>> list = new List<Tuple<int, double>>()
        {
            new Tuple<int, double>(1, 10.5),
            new Tuple<int, double>(2, 5.75),
            new Tuple<int, double>(3, 7.3),
            new Tuple<int, double>(4, 3.8),
            new Tuple<int, double>(5, 9.1)
        };

        // 使用 LINQ 来找到 double 的最小值对应的项
        var minItem = list.Aggregate((min, next) => next.Item2 < min.Item2 ? next : min);

        Console.WriteLine($"The item with the minimum double value is: ({minItem.Item1}, {minItem.Item2})");
    }
}

解释

  1. List<Tuple<int, double>>: 创建一个包含 Tuple<int, double> 的列表。每个元组包含一个整数和一个双精度浮点数。

  2. LINQ Aggregate 方法: list.Aggregate((min, next) => next.Item2 < min.Item2 ? next : min) 使用 LINQ 的 Aggregate 方法来找到 double 最小值对应的项。这里的 Aggregate 方法接受两个参数,minnext,并通过比较 next.Item2min.Item2 来更新 min,从而找到具有最小 double 值的项。

  3. 输出结果: 将找到的具有最小 double 值的项打印出来。

输出结果

运行上述代码后,控制台将输出:

The item with the minimum double value is: (4, 3.8)

使用其他方法

你还可以使用 LINQ 的 OrderBy 方法来实现同样的结果:

var minItem = list.OrderBy(t => t.Item2).First();
Console.WriteLine($"The item with the minimum double value is: ({minItem.Item1}, {minItem.Item2})");

这种方法首先按照 double 值对列表进行排序,然后使用 First() 方法获取排序后的第一个元素,即 double 值最小的项。

这两种方法都可以找到 Tuple<int, double> 列表中 double 最小值对应的项。选择哪种方法取决于个人偏好和具体场景。

c# 可以保存三个或多个数据的容器

在C#中,如果你想要一个可以保存三个数据的容器,并且这三个数据具有不同的类型(例如int、double和string),你可以使用多种方法。以下是一些常见的选择:

使用元组 (Tuple)
你可以使用Tuple<T1, T2, T3>来保存三个不同类型的值。但是,元组在C# 7及更高版本中通常通过值元组语法(ValueTuple)来创建,它们比传统的System.Tuple更高效。

csharp

var triplet = (1, 3.14, "Hello"); // 这是一个ValueTuple

但是,请注意,值元组(ValueTuple)在.NET Framework 4.7及更高版本中可用,或者你可以通过安装System.ValueTuple NuGet包在更早的框架版本中使用它们。

定义自己的类
你可以定义一个简单的类来封装这三个值。

csharp

public class Triplet  
{  
    public int IntValue { get; set; }  
    public double DoubleValue { get; set; }  
    public string StringValue { get; set; }  
  
    public Triplet(int intValue, double doubleValue, string stringValue)  
    {  
        IntValue = intValue;  
        DoubleValue = doubleValue;  
        StringValue = stringValue;  
    }  
}  

// 使用

Triplet myTriplet = new Triplet(1, 3.14, "Hello");

这种方法提供了更好的类型安全,并且可以通过属性名来访问每个值,这使得代码更具可读性。

使用匿名类型
在LINQ查询中,你可以使用匿名类型来临时存储结果。但是,它们主要用于查询结果的投影,并且通常不会跨方法边界使用。

csharp

var anonymousType = new { Int = 1, Double = 3.14, String = "Hello" };

请注意,匿名类型主要在定义它们的同一方法中使用,并且不能跨方法边界传递。

使用数组或列表的变体
虽然数组或列表通常用于存储相同类型的元素,但你可以使用object[]或List来存储不同类型的值。然而,这种方法会牺牲类型安全,并且你可能需要在访问值时进行类型转换。

csharp

List<object> list = new List<object> { 1, 3.14, "Hello" };  

// 访问时需要类型转换,例如:(int)list[0]
在实际应用中,定义自己的类通常是最佳选择,因为它提供了类型安全、可读性,并且易于扩展和维护。

  • 47
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值