C#leetcode刷题929独特的电子邮件地址

题目描述

每封电子邮件都由一个本地名称和一个域名组成,以 @ 符号分隔。

例如,在 alice@leetcode.com中, alice 是本地名称,而 leetcode.com 是域名。

除了小写字母,这些电子邮件还可能包含 ',' 或 '+'

如果在电子邮件地址的本地名称部分中的某些字符之间添加句点('.'),则发往那里的邮件将会转发到本地名称中没有点的同一地址。例如,"alice.z@leetcode.com” 和 “alicez@leetcode.com” 会转发到同一电子邮件地址。 (请注意,此规则不适用于域名。)

如果在本地名称中添加加号('+'),则会忽略第一个加号后面的所有内容。这允许过滤某些电子邮件,例如 m.y+name@email.com 将转发到 my@email.com。 (同样,此规则不适用于域名。)

可以同时使用这两个规则。

给定电子邮件列表 emails,我们会向列表中的每个地址发送一封电子邮件。实际收到邮件的不同地址有多少?

示例

输入:["test.email+alex@leetcode.com","test.e.mail+bob.cathy@leetcode.com","testemail+david@lee.tcode.com"]
输出:2
解释:实际收到邮件的是 "testemail@leetcode.com" 和 "testemail@lee.tcode.com"。

解题

public class Solution {
    public int NumUniqueEmails(string[] emails) {
        HashSet<string> set = new HashSet<string>();
            for (int i = 0; i < emails.Count(); i++)
            {
                //本地名称
                string name = emails[i].Substring(0, emails[i].IndexOf("@"));
                //域名
                string domain = emails[i].Substring(emails[i].IndexOf("@"));
                //根据指定规则解析后的本地名称,先按加号切割字符串,然后替换'.'
                string newName = name.Substring(0, name.IndexOf("+")).Replace(".", "");
                //使用HashSet去重
                set.Add(newName + domain);
            }
            return set.Count();
    }
}

知识补充 

 1.在C#中引入HashSet

 https://www.cnblogs.com/Javi/p/6794660.html

在.NET框架中,有几个类可用于执行这些操作。一些课程如下:

  • 列表
  • 字典
  • 哈希集
  • 队列

集合

在C#编程中,像ArrayList,List这样的集合,只需添加其中的值,而不检查任何重复。为了避免这种重复的数据存储,.NET提供集合名称集。这是一个具有不同项目的集合类型。

有两种类型的集合,SortedSet和HastSet。SortedSet按照排序顺序存储数据,也可以消除重复。

哈希集 vs SortedSet

这两个类都存储非重复的项目。但是,如果要执行性能,并且不关心项目是否未分类存储,则进入HashSet。但是,如果您希望项目在插入后进行排序,但可以进行性能打击,请选择“排序”。

本文分为六个部分,分别如下:

第1节:HastSet的特点 
第2节:消除HashSet中的重复数据条目 
第3节:使用UnionWith()方法修改HashSet方法 
第4节:使用ExceptWith()方法 
修改Hashset第5节:使用SymmetricExceptWith()方法修改Hashset 
第6节:检查添加,删除等操作的性能,包含HashSet和List。

让我们开始吧

第1节:HastSet的特点

这是HashSet的一些突出特点。

  • 这个类代表一组值。
  • 这个类提供了高性能的操作。
  • 这是一组不包含重复元素的集合,并且其中存储的元素没有特定的顺序。
  • 在.NET Framework 4.6版本中,HashSet 实现IReadOnlyCollection 界面连同ISet 接口。
  • 哈希集类对其中存储的元素数量没有任何最大容量。随着元素数量的增加,这种容量不断增加。

第2节:消除C#HashSet中的重复

步骤1:打开Visual Studio并创建名称为CS_Using_HashSet的控制台应用程序。

步骤2:在Program.cs的Main()方法中,添加以下代码

using System;

using System.Collections.Generic;

 

namespace CS_Using_HashSet

{

    class Program

    {

        static void Main(string[] args)

        {

            Console.WriteLine("Using HashSet");

            //1. Defining String Array (Note that the string "mahesh" is repeated)

            string[] names = new string[] {

                "mahesh",

                "vikram",

                "mahesh",

                "mayur",

                "suprotim",

                "saket",

                "manish"

            };

            //2. Length of Array and Printing array

            Console.WriteLine("Length of Array " + names.Length);

            Console.WriteLine();

            Console.WriteLine("The Data in Array");

            foreach (var n in names)

            {

                Console.WriteLine(n);

            }

 

            Console.WriteLine();

            //3. Defining HashSet by passing an Array of string to it

            HashSet< string > hSet = new HashSet< string >(names);

            //4. Count of Elements in HashSet

            Console.WriteLine("Count of Data in HashSet " + hSet.Count);

            Console.WriteLine();

            //5. Printing Data in HashSet, this will eliminate duplication of "mahesh"

            Console.WriteLine("Data in HashSet");

            foreach (var n in hSet)

            {

                Console.WriteLine(n);

            }    

            Console.ReadLine();

        }

    }

}

上述代码具有以下规格(注:代码中的注释号与以下编号相符)

1.声明一个名称名称的字符串数组,它在其中存储名称。该数组具有字符串“mahesh”的重复条目。

2.打印其中的数组长度和数据。

3.定义一个类型为字符串的HashSet 。该对象使用数组进行初始化,该数组自动从数组中添加HashSet中的项。

4.如第1节所述,HashSet对象不允许重复输入,因此结果将显示HashSet中存在的数据的计数小于数组计数。

5.在HashSet中显示数据。

运行应用程序,并显示以下结果:

哈希集 - 重复消除

第3节:使用UnionWith()方法修改HashSet

UnionWith()方法用于修改HashSet,以包含其中存在的所有元素以及与其建立联合的其他(IEnumerable)集合中的元素。

以下代码是UnionWith()上的实现。

步骤1:在项目的Main()方法中添加以下代码。

string[] names1 = new string[] {

    "mahesh","sabnis","manish","sharma","saket","karnik"

};

 

string[] Names2 = new string[] {

    "suprotim","agarwal","vikram","pendse","mahesh","mitkari"

};

//2.

 

HashSet< string > hSetN1 = new HashSet< string >(Names1);

Console.WriteLine("Data in First HashSet");

foreach (var n in hSetN1)

{

    Console.WriteLine(n);

}

Console.WriteLine("_______________________________________________________________");

HashSet< string > hSetN2 = new HashSet< string >(names2);

Console.WriteLine("Data in Second HashSet");

foreach (var n in hSetN2)

{

    Console.WriteLine(n);

}

Console.WriteLine("________________________________________________________________");

//3.

Console.WriteLine("Data After Union");

hSetN1.UnionWith(hSetN2);

foreach (var n in hSetN1)

{

    Console.WriteLine(n);

}

以上代码具有以下规格(注:以下编号与注释相符)。

数组对象声明Name1和Names2,其中包含字符串数据。

2.本步骤定义了两个HashSet的对象hSetN1和hSetN2基于names1和names2分别和来自两个HashSet的数据被打印。

此步骤在hSetN1上调用UnionWith()方法,并将hSetN2 对象传递给它,并在union之后显示hSetN1中的所有数据。

运行应用程序,将显示以下结果:

hashset-unionwith

第4节:使用ExceptWith()方法修改哈希集

该方法用于通过删除与其他集合中的元素匹配的所有元素来修改HashSet。

步骤1:在Main()方法中添加以下代码。代码使用第3节中声明的hSetN2,并使用names1数组声明一个新的HashSet,该数组用于声明hSetN1。

Console.WriteLine();

Console.WriteLine("_________________________________");

Console.WriteLine("Data in HashSet before using Except With");

Console.WriteLine("_________________________________");

//storing data of hSetN3 in temporary HashSet

HashSet< string > hSetN3 = new HashSet< string >(names1);

foreach (var n in hSetN3)

{

    Console.WriteLine(n);

}

Console.WriteLine();

Console.WriteLine("_________________________________");

Console.WriteLine("Using Except With");

Console.WriteLine("_________________________________");

hSetN3.ExceptWith(hSetN2);

foreach (var n in hSetN3)

{

    Console.WriteLine(n);

}

运行应用程序后,将显示以下结果:

除了结果

上述结果表明,当通过将hSetN2参数传递给hSetN2 HashSet的ExceptWith()方法时,从hSetN3中删除匹配的字符串“mahesh”,并显示剩余的字符串。

 

第5节:使用 SymmetricExceptWith()方法修改Hashset

 

此方法修改HashSet对象以包含仅存在于两个集合之一中的那些元素,但不能同时包含两个。

所有匹配的元素将被删除。

步骤1:在Main()方法中添加以下代码。代码useshSetN2在第3节中声明,并使用数组names1声明一个新的HashSet hSet4。

HashSet< string > hSetN4 = new HashSet< string >(names1);

Console.WriteLine("_________________________________");

Console.WriteLine("Elements in HashSet before using SymmetricExceptWith");

Console.WriteLine("_________________________________");

Console.WriteLine("HashSet 1");

foreach (var n in hSetN4)

{

    Console.WriteLine(n);

}

Console.WriteLine("HashSet 2");

foreach (var n in hSetN2)

{

    Console.WriteLine(n);

}

Console.WriteLine("_________________________________");

Console.WriteLine("Using SymmetricExceptWith");

Console.WriteLine("_________________________________");

hSetN4.SymmetricExceptWith(hSetN2);

foreach (var n in hSetN4)

{

    Console.WriteLine(n);

}

通过将hSetN2 HashSet传递给它,在HSetN4 HashSet上调用SymmetircExceptWith()方法。这两个HashSets都包含一个字符串名称“mahesh”。

通过消除匹配的条目,hSetN4将与hSetN2的值合并。运行应用程序后,结果如下:

对称除结果

第6节:检查HashSet vs List上的添加,删除,包含操作的性能。

以上所有部分都介绍了HashSet的各种方法。

但是,当开发人员想要根据性能选择最合适的集合类型作出决定时,重要的是要检查哪些操作经常在集合上执行。

通常,添加,删除,包含是对内存中集合执行的操作。要执行List和HashSet之间的添加,删除和包含操作的比较,使用以下字符串数组。(注:您可以使用任何其他数据)

static string[] names = new string[] {

    "Tejas", "Mahesh", "Ramesh", "Ram", "GundaRam", "Sabnis", "Leena",

    "Neema", "Sita" , "Tejas", "Mahesh", "Ramesh", "Ram",

    "GundaRam", "Sabnis", "Leena", "Neema", "Sita" ,

    "Tejas", "Mahesh", "Ramesh", "Ram", "GundaRam",

    "Sabnis", "Leena", "Neema", "Sita" , "Tejas",

    "Mahesh", "Ramesh", "Ram", "GundaRam", "Sabnis",

    "Leena", "Neema", "Sita",

    "Tejas", "Mahesh", "Ramesh", "Ram", "GundaRam", "Sabnis", ……            };

(字符串总数为:550)

将以下方法添加到Program.cs

static void Get_Add_Performance_HashSet_vs_List()

{

     

    Console.WriteLine("____________________________________");

    Console.WriteLine("List Performance while Adding Item");

    Console.WriteLine();

    List< string > lstNames = new List< string >();

    var s2 = Stopwatch.StartNew();

    foreach (string s in names)

    {

        lstNames.Add(s);

    }

    s2.Stop();

 

    Console.WriteLine(s2.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();

    Console.WriteLine("Ends Here");

    Console.WriteLine();

    Console.WriteLine("____________________________________");

    Console.WriteLine("HashSet Performance while Adding Item");

    Console.WriteLine();

    

    HashSet< string > hStringNames = new HashSet< string >(StringComparer.Ordinal);

    var s1 = Stopwatch.StartNew();

    foreach (string s in names)

    {

        hStringNames.Add(s);

    }

    s1.Stop();

 

    Console.WriteLine(s1.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();

    Console.WriteLine("Ends Here");

    Console.WriteLine("____________________________________");

    Console.WriteLine();

    

}

HashSet vs List - Add()方法

上述方法通过从名称数组中迭代字符串对List和HashSet执行Add()操作。

操作的性能是通过计算秒表从类System.Diagnostics程序命名空间。

运行应用程序,并显示以下结果:

请注意,下面的结果显示了时间差我的机器,它可以执行样本时,您的计算机上有所不同。

加成项目

与HashSet相比,List <>花费更少的时间来添加字符串。

原因之一是List.Add()只是将一个项目添加到列表,而HashSet.Add()将跳过新项目(如果它等于其中一个现有项目)。与List.Add()方法相比,这需要时间来执行HashSet.Add()方法。

HashSet vs List - Contains()方法

在Program.cs中添加以下方法

static void Get_Contains_Performance_HashSet_vs_List()

{

  

    Console.WriteLine("____________________________________");

    Console.WriteLine("List Performance while checking Contains operation");

    Console.WriteLine();

    List< string > lstNames = new List< string >();

    var s2 = Stopwatch.StartNew();

    foreach (string s in names)

    {

        lstNames.Contains(s);

    }

    s2.Stop();

 

    Console.WriteLine(s2.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();

    Console.WriteLine("Ends Here");

    Console.WriteLine();

    Console.WriteLine("____________________________________");

    Console.WriteLine("HashSet Performance while checking Contains operation");

    Console.WriteLine();

 

    HashSet< string > hStringNames = new HashSet< string >(StringComparer.Ordinal);

    var s1 = Stopwatch.StartNew();

    foreach (string s in names)

    {

        hStringNames.Contains(s);

    }

    s1.Stop();

 

    Console.WriteLine(s1.Elapsed.TotalMilliseconds.ToString("0.000 ms"));

    Console.WriteLine();

    Console.WriteLine("Ends Here");

    Console.WriteLine("____________________________________");

    Console.WriteLine();

 

}

上述方法检查List和HashSet是否包含作为输入参数传递给Contains()方法的项。运行应用程序,结果将显示如下图所示

包含操作

结果清楚地表明,HashSet提供了比List更快的查找元素。

这是因为HashSet中没有重复的数据。HashSet为其中的每个项目维护哈希,并将它们排列在单独的桶中,​​其中包含存储在HashSet中的项目的每个字符的散列。

当查找发生时,HashSet会将其从第一个字符开始进行散列并将其跳转到匹配的每个字符,并从HashSet中提取元素。

HashSet vs List - Remove()方法

在Program.cs中添加以下方法

static void Get_Remove_Performance_HashSet_vs_List()

{

   

    Console.WriteLine("____________________________________");

    Console.WriteLine("List Performance while performing Remove item operation");

    Console.WriteLine();

    List< string > lstNames = new List< string >();

    var s2 = Stopwatch.StartNew();

    foreach (string s in names)

    {

        lstNames.Remove(s);

    }

    s2.Stop();

 

    Console.WriteLine(s2.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();

    Console.WriteLine("Ends Here");

    Console.WriteLine();

    Console.WriteLine("____________________________________");

    Console.WriteLine("HashSet Performance while performing Remove item operation");

    Console.WriteLine();

 

    HashSet< string > hStringNames = new HashSet< string >(StringComparer.Ordinal);

    var s1 = Stopwatch.StartNew();

    foreach (string s in names)

    {

        hStringNames.Remove(s);

    }

    s1.Stop();

 

    Console.WriteLine(s1.Elapsed.TotalMilliseconds.ToString("0.000 ms"));            Console.WriteLine();

    Console.WriteLine("Ends Here");

    Console.WriteLine("____________________________________");

    Console.WriteLine();

 

}

上述方法使用Remove()方法执行List和HashSet上的删除操作。运行应用程序,结果将显示如下图所示:

执行删除操作

上图清楚地显示了HashSet的删除操作比List更快。“删除”操作也与“包含”操作类似。

Thanks & Best Regards! Javi Zhu 朱佳辉 Mobile: 15900467108 Email: Javi.zhu@outlook.com

 2.C#中字符串的操作

 原文链接:

https://www.cnblogs.com/whl4835349/p/5736430.html

 1.Replace(替换字符)

public string Replace(char oldChar,char newChar);在对象中寻找oldChar,如果寻找到,就用newChar将oldChar替换掉。

string str = "abcde";
string newStr = str.Replace('a','x');
Console.WriteLine(newStr);

public string Replace(string oldString,string newString);在对象中寻找oldString,如果寻找到,就用newString将oldString替换掉。

string st = "abcdef";
string newstring = st.Replace("abc", "xyz");
 Console.WriteLine(newstring); 

2.Remove(删除字符)

public string Remove(int startIndex);从startIndex位置开始,删除此位置后所有的字符(包括当前位置所指定的字符)。

string str = "abcde";
string newStr=str.Remove(4);
Console.WriteLine(newStr);//输出abcd

 public string Remove(int startIndex,int count);从startIndex位置开始,删除count个字符。

string str = "abcde";
string newStr=str.Remove(2,2);
Console.WriteLine(newStr);//输出abe

3.Substring(字符串提取)

public string Substring(int startIndex);从startIndex位置开始,提取此位置后所有的字符(包括当前位置所指定的字符)。

string str = "abcde";
string newStr = str.Substring(2);
 Console.WriteLine(newStr);//输出cde

 public string Substring(int startIndex,int count);从startIndex位置开始,提取count个字符。

string str = "abcde";
string newStr = str.Substring(2,2);
Console.WriteLine(newStr);//输出cd

 

4.Trim(清空空格)

public string Trim ():将字符串对象包含的字符串       两边   的空格去掉后返回

public string Trim ( params char[] trimChars ):从此实例的开始和末尾移除数组中指定的一组字符的所有匹配项。

string str ="abcdef";
string newStr = str.Trim(new char[] {'a'});//寻找st字符串中开始与末尾是否有与'a'匹配,如有,将其移除。
Console.WriteLine(newStr); //即:bcdef

注:如果字符串为"aaaabcdef",返回依然为bcdef。当移除第一个a时,开始依然为a,继续移除,直到没有。
public string TrimEnd ( params char[] trimChars ):对此实例末尾与指定字符进行匹配,true则移除
public string TrimStart ( params char[] trimChars ):对此实例开始与指定字符进行匹配,true则移除

 

5.ToLower(转换大小写)

public string ToLower():将字符串对象包含的字符串中的大写全部转换为小写

6.IndexOf(获取指定的字符串的开始索引)

public int IndexOf (sring field):在此实例中寻找field,如果寻找到,返回开始索引,反之,返回-1

string str = "abcdef";
int num = str.IndexOf("bcd");
Console.WriteLine(num);  //即:1

7.Equals(是否相等)

public bool Equals (string value):比较调用方法的字符串对象包含字符串和参数给出的对象是否相同,如相同,就返回true,反之,返回false。

string a = "abcdef";
bool b = a.Equals("bcdef");
Console.WriteLine(b);//即:false

 public bool Equals ( string value, StringComparison comparisonType ):比较调用方法的字符串对象包含字符串和参数给出的对象是否在不区分大小写的情况下相同,如相同,就返回true,反之,返回false,第二个参数将指定区域性、大小写以及比较所用的排序规则.

string a = "ABCDEF";
bool b = a.Equals("abcdef", StringComparison.CurrentCultureIgnoreCase);
Console.WriteLine(b);//即:true

8.Split(拆分)

public string[] Split ( params char[] separator ):根据separator 指定的没有字符分隔此实例中子字符串成为Unicode字符数组, separator可以是不包含分隔符的空数组或空引用。
public string[] Split ( char[] separator, int count ):参数count 指定要返回的子字符串的最大数量

            string st = "语文|数学|英语|物理";
            string[] split = st.Split(new char[] { '|' }, 3);
            for (int i = 0; i < split.Length; i++)
            {
                Console.WriteLine(split[i]);
            }
            /*
             语文
             数学
             英语|物理
             */
            //注:count不填则全部拆分

public enum StringSplitOptions 
成员名称            说明
None                返回值包括含有空字符串的数组元素//
RemoveEmptyEntries  返回值不包括含有空字符串的数组元素

string[] split = st.Split(new char[]{'|'},StringSplitOptions.None);
string[] split = st.Split(new char[]{'|'},StringSplitOptions.RemoveEmptyEntries);

string st = "语文|数学||英语|物理";
            string[] split = st.Split(new char[]{'|'},StringSplitOptions.RemoveEmptyEntries);
            for (int i = 0; i < split.Length; i++)
            {
                Console.WriteLine(split[i]);
            }

 

9.Contains(判断是否存在)

public bool Contains(string text):如果字符串中出现text,则返回true,反之false,如果text为("")也返回true。

 string st="语文数学英语";
 bool b=st.Contains("语文");
 Console.WriteLine(b);//true

 

10.EndsWith  StartsWith(判断是否存在)

public bool EndsWith ( string value ):判断对象包含字符串是否以value指定的字符串结束,是则为 true;否则为 false。 
public bool EndsWith ( string value, StringComparison comparisonType ):第二个参数设置比较时区域、大小写和排序规则。
public bool StartsWith ( string value ):判断对象包含字符串是否以value指定的字符串开始,是则为 true;否则为 false。 
public bool StartsWith ( string value, StringComparison comparisonType ) :第二个参数设置比较时区域、大小写和排序规则。

string st = "语文数学英语abc";
bool b = st.EndsWith("英语ABC", StringComparison.CurrentCultureIgnoreCase);//第二个参数忽略大小比较。
Console.WriteLine(b);//true

11.Insert(字符插入)

public string Insert ( int startIndex, string value ):在指定的字符串下标为startIndex前插入字符串value。返回插入后的值。

string st="语文数学英语abc";
 string newst=st.Insert(6,"物理");//注:在指定索引“前”插入。
 Console.WriteLine(newst);//即:语文数学英语物理abc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值