首页 > 代码库 > 字符串按首字母分组并ToDictionary的实现

字符串按首字母分组并ToDictionary的实现

  这是携程(深圳).net开发笔试的一道题目,要求实现字符串按首字母分组并ToDictionary输出,当时没有做出来,后面研究了一下,现在将这道题的几种实现方式记录下来。

首先初始化数据源,是一个List<string>对象。如下代码。

//数据源
            List<string> list = new List<string> 
            {
                "Beijing", "Shanghai", "Tianjin", "Chongqing", "Harbin", "Dalian", "Qingdao", "Xi‘an",   
                "Dunhuang", "Nanjing", "Wuxi", "Suzhou", "Yangzhou", "Zhenjiang", "Hangzhou", "Xitang",   
                "Zhoushan", "Chun‘an", "Qiandaohuzhen", "Shaoxing", "Huangshan", "Jiujiang", "Xiamen",  
                "Wuyi Shan", "Zhangjiajie", "Chengdu", "Shenzhen", "Zhuhai", "Guangzhou", "Guilin",   
                "Kunming", "Xishuangbanna", "Dali", "Lijiang", "Guiyang", "Urumqi", "Turpan", "Lhasa"
            };

第一种分组方法,使用正则表达式,代码如下。

        /// <summary>
        /// 使用正则表达式匹配
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static string GetGroupNameByRegex(char str)
        {
            string sInput = str.ToString();
            if (Regex.IsMatch(sInput, "[a-gA-G]", RegexOptions.IgnoreCase))
            {
                return "A-G";
            }
            if (Regex.IsMatch(sInput, "[h-nH-N]", RegexOptions.IgnoreCase))
            {
                return "H-N";
            }
            return "O-Z";
        }

第二种方法,直接比较两个char,代码如下。

        /// <summary>
        /// 方法二:使用字符的ASCII码大小匹配
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static string GetGroupNameByCharASCII(char str)
        {
            if ((str >= a && str <= g) || (str >= A && str <= G)) //char可以隐式地转换为int
            {
                return "A-G";
            }
            if ((str >= h && str <= n) || (str >= H && str <= N))
            {
                return "H-N";
            }
            return "O-Z";
        }

注意,两个char之所以能直接比较大小,实际上char先被转换成了int,也就是对应的ASCII码,然后才进行比较大小的。

第三种方法,实际上跟第二种方法相同,只不过在方法二的基础上进行了优化,代码如下。

        /// <summary>
        /// 方法二的升级版
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static string GetGroupNameByCharASCII1(char str)
        {
            char newChar = Char.ToLower(str);
            //if (newChar >= ‘o‘)
            //{
            //    return "O-Z";
            //}
            //if (newChar>=‘h‘)
            //{
            //    return "H-N";
            //}
            //return "A-G";
            return newChar >= o ? "O-Z" : newChar >= h ? "H-N" : "A-G";
        }

需要注意的是,方法三的写法,多个if...else...语句可以使用三元操作符来化简,使代码更优雅。

输出结果,代码如下。

var query = list.GroupBy(p =>
{
    return GetGroupNameByRegex(p[0]);
}).ToDictionary(p => p.Key, p => p);
foreach (var item in query)
{
    Console.WriteLine("{0}", item.Key);//IGrouping<TKey,TValue>
    foreach (var subItem in item.Value)
    {
        Console.WriteLine("  {0}", subItem);
    }
}
Console.ReadKey();

输出结果截图如下。