【转】一道笔试题的解法和联想

转自:http://www.cnblogs.com/nuaalfm/archive/2008/08/23/1274868.html



原题是这样的,请用C#编写一个可以对任意类型进行冒泡排序算法,我们先看一个整型的冒泡排序来了解一下冒泡排序:

 


static void Main(string[] args)
        {
            
int[] array = { 9,8,2,6,5,4,3,7,1};
            BubleSort(array);
            
for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine(array[i]);
            }
        }
        
static void BubleSort(int[] array)
        {
            
for (int i = 0; i < array.Length; i++)
            {
                
for (int j = 0; j < array.Length-i-1; j++)
                {
                    
if (array[j] > array[j + 1])
                    {
                        
int temp = array[j];
                        array[j] 
= array[j + 1];
                        array[j 
+ 1= temp;
                    }
                }
            }
        }

 

这个题其实考的重点并不在冒泡排序(当然不懂冒泡排序肯定不行),而是考一种抽象能力,对于冒泡排序来说,任意类型排序他们共同的东西就是冒泡排序的思想,而不同的部分在比较上,所以我们就要想一种方法将变化的部分和不变的部分隔离开,我们首先想到的方法是使用接口,下边是一种解法:

 


public interface IArray
    {
        
bool Compare(IArray IA);
    }
    
public class Employee:IArray
    {
        
public Employee(int age)
        {
            
this.Age = age;
        }
        
public int Age { getset; }
        
public bool Compare(IArray IA)
        {
            
return this.Age>((Employee)IA).Age;
        }
    }
    
class Program
    {
        
static void Main(string[] args)
        {
            Employee[] array 
= { new Employee(23),new Employee(20),new Employee(19),new Employee(30)};
            BubleSort(array);
            
for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine(array[i].Age);
            }
        }
        
static void BubleSort(IArray[] array)
        {
            
for (int i = 0; i < array.Length; i++)
            {
                
for (int j = 0; j < array.Length-i-1; j++)
                {
                    
if (array[j].Compare(array[j + 1]))
                    {
                        IArray temp 
= array[j];
                        array[j] 
= array[j + 1];
                        array[j 
+ 1= temp;
                    }
                }
            }
        }
    }

 

这个解法可以应对更多的类型排序,只要这些需要排序的类型都实现IArray接口就可以了,但是问题是如果这样,这个排序算法又不支持整型了,我们总不能为了这个排序算法重新封装一下整型吧。我们得继续寻找办法,于是我们想到了系统的一个接口IComparable,这个接口定义通用的比较方法,由值类型或类实现以创建类型特定的比较方法。系统自定义类型几乎都实现了这个接口,所以只要自定义类也实现这个接口就可以利用到这里了,代码如下:

 

接口实现2

 

现在基本符合题意了,但看起来好像还不是好的解决方案,因为每个类型都要实现IComparable仍然是个限制,那如何打破这个限制呢,仔细想想,我们想出另外一个解决方案,就是想办法把比较方式封装起来,然后调用排序函数时传进来不就成了么。

 


class IntCompare:IComparer<int>
    {
        
public int Compare(int x, int y)
        {
            
return x.CompareTo(y);
        }

    }
    
class Program
    {
        
static void Main(string[] args)
        {
            
//Employee[] array = { new Employee(23),new Employee(20),new Employee(19),new Employee(30)};
            int[] array = { 982654371 };
            BubleSort
<int>(array,new IntCompare());
            
for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine(array[i]);
            }
        }

        
static void BubleSort<T>(T[] array,IComparer<T> compare)
        {
            
for (int i = 0; i < array.Length; i++)
            {
                
for (int j = 0; j < array.Length-i-1; j++)
                {
                    
if (compare.Compare(array[j], array[j + 1]) > 0)
                    {
                        T temp 
= array[j];
                        array[j] 
= array[j + 1];
                        array[j 
+ 1= temp;
                    }
                }
            }
        }
    }

 

大家可能觉得这个和上一个方案很象阿,不都要实现一个接口么,其实后一个方案中的最大优点在于你自定义类不用继承任何接口了,我们想一下,为了让某个类型支持这个冒泡排序而去实现一个接口是很牵强的。那这个是不是最好的解决方案呢,我们本着不撞南墙不回头的原则继续前进,这个接口好像用委托也可以实现吧,那写个版本先:

 

委托实现

 

似乎也没有什么改进,还要写多写一个方法,但是这个委托版本已经基本接近我们的答案了,下面我们使用Lambda表达式来实现我认为的最优的答案(这个答案中需要大家了解Lambda表达式,范型以及Func委托):

 


class Program
    {
        
static void Main(string[] args)
        {
            
//Employee[] array = { new Employee(23),new Employee(20),new Employee(19),new Employee(30)};
            int[] array = { 982654371 };
            BubleSort
<int>(array, (a,b)=>a>b);
            
for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine(array[i]);
            }
        }
        
static void BubleSort<T>(T[] array, Func<T,T,bool> compare)
        {
            
for (int i = 0; i < array.Length; i++)
            {
                
for (int j = 0; j < array.Length-i-1; j++)
                {
                    
if (compare(array[j], array[j + 1]))
                    {
                        T temp 
= array[j];
                        array[j] 
= array[j + 1];
                        array[j 
+ 1= temp;
                    }
                }
            }
        }
    }
posted @ 2008-08-24 02:58  么么茶.NET  阅读(288)  评论(0编辑  收藏  举报