黑马程序员技术交流社区

标题: 一道囊括了冒泡、正则、委托、Lamda表达式的综合题排序题 [打印本页]

作者: 张向阳    时间: 2012-12-13 15:26
标题: 一道囊括了冒泡、正则、委托、Lamda表达式的综合题排序题
首先我们来看一下最常规的做法:
    class Program
    {
        static void Main(string[] args)
        {
            string[] strs = {
                               "黑马.net第5期就要开班了!",
                               "黑马老师3都很牛x!",
                               "ASP.NET 1",
                               "C#基础教程 2",
                               "SQL2008",
                               "VS2010"
                           };
            SortWithLength(strs);      //调用方法按照长度排序
            //-----------------------------------------------------
            SortWithDic(strs);         //按照字典规则进行排序
            //-----------------------------------------------------
            SortWithFirstNum(strs);    //按照出现的第一个数字进行排序
            //-----------------------------------------------------
            for (int i = 0; i < strs.Length; i++)
            {
                Console.WriteLine(strs);
            }
            Console.ReadKey();
        }

        //方法一、按照字符串长度进行排序
        public static void SortWithLength(string[] strs)
        {
            for (int i = 0; i < strs.Length - 1; i++)
            {
                for (int j = 0; j < strs.Length - 1 - i; j++)
                {
                    if (strs[j].Length > strs[j + 1].Length)    //按照串的长度进行比较
                    {
                        string tem = strs[j];
                        strs[j] = strs[j + 1];
                        strs[j + 1] = tem;
                    }
                }
            }
        }

        //方法二、按照字典规则进行排序
        public static void SortWithDic(string[] strs)
        {
            for (int i = 0; i < strs.Length - 1; i++)
            {
                for (int j = 0; j < strs.Length - 1 - i; j++)
                {
                    //按照字典规则进行比较,前者大于后者结果为1,两者相等结果为0,前者小于后者结果为-1
                    //条件设置成大于0或等于1都可;
                    if (string.Compare(strs[j], strs[j + 1]) > 0)
                    {
                        string tem = strs[j];
                        strs[j] = strs[j + 1];
                        strs[j + 1] = tem;
                    }
                }
            }
        }

        //方法三、按照字符串中出现的第一个数字进行排序
        public static void SortWithFirstNum(string[] strs)
        {
            for (int i = 0; i < strs.Length - 1; i++)
            {
                for (int j = 0; j < strs.Length - 1 - i; j++)
                {
                    //通过正则表达式匹配到第一个出现的字符串数字,然后通过Convert转换成数字进行比较即可!
                    //注:Regex需要导入命名空间,快捷方式为光标放在Regex上,按Shift+Alt+F10即可,其它的亦然!
                    if (Convert.ToInt32(Regex.Match(strs[j], @"\d+").Value) > Convert.ToInt32(Regex.Match(strs[j + 1], @"\d+").Value))
                    {
                        string tem = strs[j];
                        strs[j] = strs[j + 1];
                        strs[j + 1] = tem;
                    }
                }
            }
        }


作者: 张向阳    时间: 2012-12-13 15:35
下面通过委托的方法来实现排序 :
//由于在实际工作中客户的要求是多种多样的,一旦客户的需求发生改变要求重新排序,我们就得到源码中去修改排序方法,非常不方便!观察上面的比较方法我们不难发现,除了if语句里面的比较方法不同之外,其它的都是重复代码,这时候我们就可以考虑用委托来实现了,委托的实质其实就是将方法当变量来使用

public delegate bool MyCompareDelegate(string str1,string str2);//声明一个委托
class Program
{
       static void Main(string[] args)
        {
            string[] strs = {
                               "黑马.net第5期就要开班了!",
                               "黑马老师3都很牛x!",
                               "ASP.NET 1",
                               "C#基础教程 2",
                               "SQL2008",
                               "VS2010"
                           };
            MyCompareDelegate compare = null;//首先声明一个委托变量,先赋初值为null
            CompareAll(strs,compare);//调用那个缺少条件的比较方法,将字符串和委托变量传进去
            compare = CompareWithLength;//将按长度比较的方法赋给委托变量
            //----------------------------------------------------------
            compare = CompareWithDic;//将按字典规则比较的方法赋给委托变量
            //----------------------------------------------------------
            compare = CompareWithFirstNum;//将数字比较方法赋给委托变量
            for (int i = 0; i < strs.Length; i++)
            {
                Console.WriteLine(strs);//将三种方法分别打印输出,查看结果,多敲几遍,仔细体会!
            }
            Console.ReadKey();
        }
        public static void CompareAll(string[] strs, MyCompareDelegate compare)
        {
            for (int i = 0; i < strs.Length-1; i++)
            {
                for (int j = 0; j < strs.Length-1-i; j++)
                {
                    //为什么我们声明委托的时候需要bool类型的,为什么需要两个参数,这里就能看出来了
                    if (compare(strs[j],strs[j+1]))
                    {
                        string tem=strs[j];
                        strs[j]=strs[j+1];
                        strs[j + 1] = tem;
                    }
                }
            }
        }
        //然后下面我们就可以根据需要灵活的定义比较的规则了,或者别人的规则直接生成dll程序集,我们直接添加
        //引用就可以用了!适用范围和灵活性都提高了,这就能体现委托的优势所在!多敲几遍,慢慢体会!
        //方法一、按字符串长度进行比较
        public static bool CompareWithLength(string str1, string str2)
        {
            return str1.Length > str2.Length;//将比较方法直接返回即可
        }
        //方法二、按字字典规则进行比较排序
        public static bool CompareWithDic(string str1,string str2)
        {
            return string.Compare(str1,str2)>0;
        }
        //方法三、按字符串中出现的第一个数字进行排序
        public static bool CompareWithFirstNum(string str1, string str2)
        {
            return Convert.ToInt32(Regex.Match(str1,@"\d+").Value) > Convert.ToInt32(Regex.Match(str2,@"\d+").Value);
        }
}

作者: 张向阳    时间: 2012-12-13 15:42
简单介绍一下匿名方法和Lambda表达式
//有些时候在程序中某些方法只有一句话或者只用一两次,而我们这时候再单独给它取个方法名写一个完整的方法感觉是不不是比较麻烦,如二楼用于定义比较的几个方法,光方法名就那么长了!程序员是伟大的,这个时候匿名方法和Lamda表达式就诞生了!
    delegate void MyDelegate();//首先定义一个无参无返回值的委托
    class Program
    {
        static void Main(string[] args)
        {
            //定义一个委托变量,用delegate引导,括弧里面用来放参数,后面是执行语句!注意:大括号后面的分号不要忘掉
            MyDelegate myfunc = delegate() { Console.WriteLine("我是一个匿名方法"); };
            myfunc();
            Console.ReadKey();
        }
    }
    delegate void MyDelegate(int x, int y);//定义一个有参数的委托
    class Program
    {
        static void Main(string[] args)
        {
            //由于定义的委托里面有变量了,所以delegate后面引导的方法也要有同样的参数
            MyDelegate myfunc = delegate(int x, int y) { Console.WriteLine("{0}+{1}={2}", x, y, x + y); };
            myfunc(100, 20);//调用的时候别忘了参数
            //上面的方法还可以用Lambda表达式进行简化
            MyDelegate myfunc = (x, y) => Console.WriteLine("{0}+{1}={2}", x, y, x + y);//如果后面有多条语句要执行,加花括号,里面可以放多条语句组成语句块!
            myfunc(100, 20);//得到和上面同样的结果
            Console.ReadKey();//查看结果,体会一下!
        }
    }

作者: 张向阳    时间: 2012-12-13 15:47
最后我们可以通过Lambda表达式来实现上面的排序问题就更简单了:
        static void Main(string[] args)
        {
            string[] strs = {
                               "黑马.net第5期就要开班了!",
                               "黑马老师3都很牛x!",
                               "ASP.NET 1",
                               "C#基础教程 2",
                               "SQL2008",
                               "VS2010"
                           };
            //用Lambda表达式按长度排序
            CompareAll(strs, (str1, str2) => str1.Length > str2.Length);
            //-----------------------------------------------------------
            //用Lambda表达式按字典规则排序
            CompareAll(strs, (str1, str2) => string.Compare(str1, str2) > 0);
            //-----------------------------------------------------------
            //用Lambda表达式按出现的第一个数字进行排序
            CompareAll(strs, (str1, str2) => Convert.ToInt32(Regex.Match(str1, @"\d+").Value) > Convert.ToInt32(Regex.Match(str2, @"\d+").Value));

            for (int i = 0; i < strs.Length; i++)
            {
                Console.WriteLine(strs);//将三种方法分别打印输出,查看结果,多敲几遍,仔细体会!
            }
            Console.ReadKey();

        }
        public static void CompareAll(string[] strs, MyCompareDelegate compare)
        {
            for (int i = 0; i < strs.Length - 1; i++)
            {
                for (int j = 0; j < strs.Length - 1 - i; j++)
                {
                    //为什么我们声明委托的时候需要bool类型的,为什么需要两个参数,这里就能看出来了
                    if (compare(strs[j], strs[j + 1]))
                    {
                        string tem = strs[j];
                        strs[j] = strs[j + 1];
                        strs[j + 1] = tem;
                    }
                }
            }
        }


作者: 李永涛    时间: 2012-12-13 17:04
学习了·····
作者: 黄新    时间: 2012-12-14 11:49
学习。。
作者: 杨占伟    时间: 2012-12-14 12:01
学习了!~~~~
作者: 王斌    时间: 2012-12-14 14:58
学习了!
作者: 王晨    时间: 2012-12-15 14:41
先记下来,慢慢学习一下,感谢分享啊:victory:




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2