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

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



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

 

ContractedBlock.gif ExpandedBlockStart.gif 整型冒泡排序
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;
                    }
                }
            }
        }

 

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

 

ContractedBlock.gif ExpandedBlockStart.gif 接口实现1
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,这个接口定义通用的比较方法,由值类型或类实现以创建类型特定的比较方法。系统自定义类型几乎都实现了这个接口,所以只要自定义类也实现这个接口就可以利用到这里了,代码如下:

 

ContractedBlock.gif ExpandedBlockStart.gif 接口实现2
class Program
    {
        
static void Main(string[] args)
        {
            
//Employee[] array = { new Employee(23),new Employee(20),new Employee(19),new Employee(30)};
            IComparable[] array = { 982654371 };
            BubleSort(array);
            
for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine(array[i]);
            }
        }
        
static void BubleSort(IComparable[] array)
        {
            
for (int i = 0; i < array.Length; i++)
            {
                
for (int j = 0; j < array.Length-i-1; j++)
                {
                    
if (array[j].CompareTo(array[j + 1])>0)
                    {
                        IComparable temp 
= array[j];
                        array[j] 
= array[j + 1];
                        array[j 
+ 1= temp;
                    }
                }
            }
        }
    }

 

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

 

ContractedBlock.gif ExpandedBlockStart.gif 接口实现3
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;
                    }
                }
            }
        }
    }

 

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

 

ContractedBlock.gif ExpandedBlockStart.gif 委托实现
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, CompareMethod);
            
for (int i = 0; i < array.Length; i++)
            {
                Console.WriteLine(array[i]);
            }
        }
        
static bool CompareMethod(int t1, int t2)
        {
            
return t1 > t2;
        }
        
delegate bool Compare<T>(T t1, T t2);
        
static void BubleSort<T>(T[] array, Compare<T> 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;
                    }
                }
            }
        }
    }

 

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

 

ContractedBlock.gif ExpandedBlockStart.gif Lambda表达式实现
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;
                    }
                }
            }
        }
    }

转载于:https://www.cnblogs.com/kangtr/archive/2008/08/24/1274940.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值