Hello World
Spiga

一道简单的编程题,不过您做对了吗?

2009-05-27 19:45 by 老赵, 29394 visits

CSDN学生中心是个好地方,如果善于利用,应该能够对大众产生正面影响。老赵也去那里安了家,并给出了一个编程问题。题目如下:

请将方法补充完整:

public static void Reverse(int[] array, int begin, int end)
{
   ...
} 

Reverse方法的作用是将array数组中,从begin下标到end下标之间的元素反序一下,如一个数组初始值是[1, 2, 3, 4, 5, 6],begin为1,end为4,那么当调用了Reverse之后,array数组中的元素便依次成为[1, 5, 4, 3, 2, 6],其中从array[1]到array[4]之前的元素被反序了。此外补充一点……其实本不用补充:这个方法需要对传入参数的正确性进行校验,如果用户调用该方法时传入了非法的参数,那么则需要抛出异常,并写清原因。您可以使用您喜欢的语言来实现:C#,VB,Java,Ruby,Python……但是请不要使用内置库中已经有的功能。:)

很简单,不是吗?只可惜截止到目前,也只有1人给出了正确答案。如果您没有做过这道题目,那么在查看下面的分析之前,不妨拿张纸拿支笔,写下您的答案,然后再听老赵慢慢讲来……(点此展开

Creative Commons License

本文基于署名 2.5 中国大陆许可协议发布,欢迎转载,演绎或用于商业目的,但是必须保留本文的署名赵劼(包含链接),具体操作方式可参考此处。如您有任何疑问或者授权方面的协商,请给我留言

Add your comment

174 条回复

  1. 侯垒
    *.*.*.*
    链接

    侯垒 2009-05-27 19:45:00

    坐老赵的沙发再看题。

  2. 金色海洋(jyk)
    *.*.*.*
    链接

    金色海洋(jyk) 2009-05-27 19:47:00

    板凳

  3. htqx[未注册用户]
    *.*.*.*
    链接

    htqx[未注册用户] 2009-05-27 19:58:00

    while (begin<end) { 
        int temp = array[begin]; 
        array[begin] = array[end]; 
        array[end] = temp; 
        begin++; 
        end++; 
    } 
    
  4. Microshaoft
    *.*.*.*
    链接

    Microshaoft 2009-05-27 20:09:00

    用数组实现一个栈 入栈 再出栈 是最容易先到的
    有一个类似的面试题
    就地翻转 in place 不使用多余的变量 “我 爱 祖国” => “祖国 爱 我”
    另外 reflector
    Array.Reverse(...)
    的确跟老赵一样

  5. Cat Chen
    *.*.*.*
    链接

    Cat Chen 2009-05-27 20:13:00

    实现语言不同,异常的范围也不同。例如很多脚本语言支持负数的index,并把这看做从Array末端进行倒数的index。在使用这些语言并保持原有风格时,异常的范围也就小了。

  6. htqx[未注册用户]
    *.*.*.*
    链接

    htqx[未注册用户] 2009-05-27 20:17:00

    看了一下,发现不友好,这个学生中心.

    不知道网上那里有给学生锻炼的在线题目做呢?
    最好照顾入门的新手.

  7. zhangxr[未注册用户]
    *.*.*.*
    链接

    zhangxr[未注册用户] 2009-05-27 20:18:00

    static void Reverse(int[] array, int begin, int end) 
    { 
        if (begin==end) return; 
        int swap = array[begin]; 
        array[begin] = array[end]; 
        array[end] = array[begin]; 
        if (end-begin!=-1) 
            Reverse(array, begin+1, end-1); 
    } 
    
  8. JimLiu
    *.*.*.*
    链接

    JimLiu 2009-05-27 20:30:00

    先给个答案,再看正文了。

    if (array == null) throw new ArgumentNullException();
    if (start < 0) throw new ArgumentOutOfRangeException();
    if (start > end) throw new ArgumentOutOfRangeException();
    if (end > array.Length) throw new ArgumentOutOfRangeException();
    while(start < end) {
        swap(ref array[start++], ref array[end--]);
    }
    

    // 以上代码不保证能编译通过:(

  9. 高歌
    *.*.*.*
    链接

    高歌 2009-05-27 20:34:00

    呵呵,这道题目老赵应用的非常好,几个知识点讲解的也非常到位,全都是学生容易犯错的地方。

    希望有空你去培训机构教教学生,或许想法会有所改观。

  10. 飞林沙
    *.*.*.*
    链接

    飞林沙 2009-05-27 20:38:00

    如果我没记错的话,我在应聘老赵公司老赵给我发邮件时出过这道题...

  11. NS[未注册用户]
    *.*.*.*
    链接

    NS[未注册用户] 2009-05-27 20:48:00

    思路相同,不过我习惯性的写了个for循环,不知道为什么会有这个习惯.

  12. funny zak
    *.*.*.*
    链接

    funny zak 2009-05-27 20:55:00

    using System; 
    using System.Collections.Generic; 
    
    public class MyClass 
    { 
        public static void Main() 
        { 
            int[] array = new int[]{1,3,4,6,9,33,22}; 
            Reverse(array,5,5); 
        } 
    
        static void Reverse(int[] array, int begin, int end) 
        { 
            if (!(array.Length < 2 || end < begin || begin < 0 || end < 0 || begin == end || begin > array.Length || end > array.Length)) 
            { 
                int count = end - begin-1; 
                for (int i = begin; i < count; i++) 
                { 
                    int temp = array[end]; 
                    array[end] = array[begin]; 
                    array[begin] = temp; 
                    begin++; 
                    end--; 
                } 
                foreach (int one in array) 
                { 
                    Console.WriteLine(one.ToString()); 
                } 
    
            } 
            else 
            { 
                Console.WriteLine("error array"); 
            } 
            Console.ReadLine(); 
        } 
    }
    
  13. funny zak
    *.*.*.*
    链接

    funny zak 2009-05-27 20:56:00

    Snippet Compiler 编译通过

  14. 银河
    *.*.*.*
    链接

    银河 2009-05-27 21:00:00

    很好的文章,对初学者很有帮助。

    请问一下楼主,在“主体逻辑”一节中,以下一句话的中“眼力”是什么意思?那么老赵眼力最好的做法是什么呢?

    还有,在“参考答案”一节中,

    throw new ArgumentOutOfRangeException("end不能小于begin", (Exception)null);
    

    为什么不直接使用:

    throw new ArgumentOutOfRangeException("end不能小于begin");
    

    谢谢!

  15. 周强
    *.*.*.*
    链接

    周强 2009-05-27 21:11:00

    来个SQL版,写着玩

    CREATE PROC TESTPROC 
    @ARRSTRING VARCHAR(MAX), 
    @BEGIN INT, 
    @END INT, 
    @EXCP_STRING NVARCHAR(20) OUTPUT 
    AS 
    
    IF(@ARRSTRING IS NULL) 
    BEGIN 
        SET @EXCP_STRING='输入的字符串为空!' 
        RETURN 
    END 
    IF(@BEGIN>@END) 
    BEGIN 
        SET @EXCP_STRING='下标错误!' 
        RETURN 
    END 
    
    DECLARE @TEMPXML XML 
    SET @TEMPXML='<tr>'+REPLACE(@ARRSTRING,',','</tr><tr>')+'</tr>' 
    
    CREATE TABLE #TEMPTABLE 
    ( 
        ZVALUE INT, 
        ORDER_ID INT NOT NULL IDENTITY(0,1) 
    ) 
    
    SELECT TOP 0 * 
    INTO #RESULT 
    FROM #TEMPTABLE 
    
    INSERT INTO #TEMPTABLE(ZVALUE) 
    SELECT A.X.value('.','INT') ZVALUE 
    FROM @TEMPXML.nodes('tr') AS A(X) 
    
    INSERT INTO #RESULT 
    SELECT ZVALUE 
    FROM #TEMPTABLE 
    WHERE ORDER_ID<@BEGIN 
    ORDER BY ORDER_ID ASC 
    
    INSERT INTO #RESULT 
    SELECT ZVALUE 
    FROM #TEMPTABLE 
    WHERE ORDER_ID BETWEEN @BEGIN AND @END 
    ORDER BY ORDER_ID DESC 
    
    INSERT INTO #RESULT 
    SELECT ZVALUE 
    FROM #TEMPTABLE 
    WHERE ORDER_ID>@END 
    ORDER BY ORDER_ID ASC 
    
    SELECT ZVALUE 
    FROM #RESULT 
    ORDER BY ORDER_ID
    
  16. CowNew开源团队
    *.*.*.*
    链接

    CowNew开源团队 2009-05-27 21:19:00

    老赵很拉风,刚到csdn就在csdn上掀起了狂潮

  17. Kevin Dai
    *.*.*.*
    链接

    Kevin Dai 2009-05-27 21:23:00

    static void Reverse(int[] array, int begin, int end) 
    { 
        if (null == array) 
        { 
            throw new ArgumentNullException("array", "parameter array can't be null"); 
        } 
        if (begin > array.Length || begin < 0 ) 
        { 
            throw new ArgumentOutOfRangeException("begin", "parameter begin must range from 0 to " + (array.Length - 1).ToString()); 
        } 
        if ( end > array.Length || end < 0) 
        { 
            throw new ArgumentOutOfRangeException("end", "parameter end must range from 0 to " + (array.Length - 1).ToString()); 
        } 
        if (end < begin) 
        { 
            throw new ArgumentException("parameter end must be greater equal than parameter begin", "end"); 
        } 
        int i = begin, j = end,temp; 
        while (i < j) 
        { 
            temp = array[i]; 
            array[i] = array[j]; 
            array[j] = temp; 
            ++i; --j; 
        } 
    }
    
  18. 在别处
    *.*.*.*
    链接

    在别处 2009-05-27 21:24:00

    菜鸟来试试

    static void Reverse(int[] array, int begin, int end) 
    { 
        if (end >= begin || end >array.Length-1 || begin < array.Length-1) 
        { 
            int len = end - begin; 
            for (int i = 0; i < len / 2; i++) 
            { 
                int temp = array[begin]; 
                array[begin] = array[end]; 
                array[end] = temp; 
                begin++; 
                end--; 
            } 
        } 
        else 
        { 
            throw new ArgumentException(); 
        }
    }
    
  19. 隐约有歌
    *.*.*.*
    链接

    隐约有歌 2009-05-27 21:24:00

    这个题目要是再出狠一点,函数的第一个参数不是 int[],而是给 Array。

    这样就要考虑到了数组的下界,不一定是 0 了啊,需要用 Array.GetLowerBound 来获取。
    数组也有可能是2维的,怎么逆转?

    可以考察程序员的全面思维能力。~

  20. hailibu
    *.*.*.*
    链接

    hailibu 2009-05-27 21:29:00

    //为了简化,这里不对索引异常处理
    private static void Reverse(int[] array,int begin,int end)
    {
        int len = end - begin + 1,temp; //len为结束索引与开始索引间的总个数,temp为临时变量
        int n=(len%2==0)?(len/2):((len-1)/2); //n为两两对调的总次数
    
        for(int i=0;i<n;i++)
        {
            temp=array[begin+i];
            array[begin+i]=array[end-i];
            array[end-i]=temp;
        }
    
        foreach(int item in array)
        {
            Console.WriteLine(item.ToString());
        }
    }
    
  21. ●阿保●
    *.*.*.*
    链接

    ●阿保● 2009-05-27 21:38:00

    呵呵,我也来一下:

    public static void Reverse(int[] array, int begin, int end) { 
        if (array == null) 
            throw new ArgumentNullException("数组不能为空!"); 
    
        if (begin > end) 
            throw new ArgumentOutOfRangeException("开始下标不能大于结束下标!"); 
    
        if (begin >= array.Length || begin < 0 ) 
            throw new ArgumentOutOfRangeException("数组越界"); 
    
        for(int i=end,j=begin;i>=begin;i--) 
        { 
            array[begin] = array[end]; 
            begin++; 
        } 
    }
    
  22. James.Ying
    *.*.*.*
    链接

    James.Ying 2009-05-27 21:40:00

    都差不多 不知道还有什么更神奇的方法不

  23. Nick Wang (懒人王)
    *.*.*.*
    链接

    Nick Wang (懒人王) 2009-05-27 21:40:00

    def reverse(array, b, e)
        raise 'array is null' unless array
        raise 'begin<0' if b<0
        raise 'end < begin' if e<b
        raise 'end is larger than array length' if e>=array.size
        while b < e do
            array[b], array[e] = array[e], array[b]
            b+=1
            e-=1
        end
        array
    end
    
  24. 孟冬伊
    *.*.*.*
    链接

    孟冬伊 2009-05-27 21:51:00

    static void Reverse(int[] array, int begin, int end) 
    { 
        try 
        { 
            if (begin < end && begin >= 0 && end >= 0) 
            { 
                for (int i = begin; i < end; i++) 
                { 
                    int temp = array[begin]; 
                    array[begin] = array[end]; 
                    array[end] = temp; 
                    begin++; 
                    end--; 
                } 
            } 
        }
    
  25. 孟冬伊
    *.*.*.*
    链接

    孟冬伊 2009-05-27 21:58:00

    我做的和赵老师的答案差不多了。。。。。。。。。。。
    我去面试不知是否会过。。。

  26. 徐少侠
    *.*.*.*
    链接

    徐少侠 2009-05-27 22:02:00

    为什么没有人考虑线程安全性?

    难道数组操作是线程安全的?

  27. hailibu
    *.*.*.*
    链接

    hailibu 2009-05-27 22:14:00

    // 我最喜欢下面这种写法。思路清晰,代码简洁
    int temp;
    while (begin<end){
        temp = array[begin];
        array[begin] = array[end];
        array[end] = temp;
        begin++;
        end--;
    }
    
  28. m j[未注册用户]
    *.*.*.*
    链接

    m j[未注册用户] 2009-05-27 22:20:00

    个人认为老赵的问题方法签名不够合适。。Array在这里反序白反了。。即使是用作简单的考题也应该有个输出比较好吧。。

  29. 老赵
    admin
    链接

    老赵 2009-05-27 22:20:00

    @htqx: 看了一下,发现不友好,这个学生中心. 不知道网上那里有给学生锻炼的在线题目做呢? 最好照顾入门的新手.

    的确不太友好,不过CSDN学生中心就有啊。

  30. 木野狐(Neil Chen)
    *.*.*.*
    链接

    木野狐(Neil Chen) 2009-05-27 22:22:00

    using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    
    namespace ConsoleApplication3 
    { 
        class Program 
        { 
            static void Main(string[] args) 
            { 
                var arr = new int[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 
    
                Reverse(arr, 1, 3); 
                Reverse(arr, 1, 3); 
                Reverse(arr, 3, 1); 
    
                Console.WriteLine(arr.Aggregate("", (result, i) 
                    => result + " " + i.ToString() 
                )); 
                Console.ReadLine(); 
            } 
    
            static void Reverse(int[] array, int begin, int end) 
            { 
                if (begin < 0 || begin > array.Length - 1) 
                    throw new ArgumentOutOfRangeException("begin"); 
    
                if (end < 0 || end > array.Length - 1) 
                    throw new ArgumentOutOfRangeException("end"); 
    
                if (begin == end) return; 
    
                int i, j, temp; 
                if (begin < end) 
                { 
                    i = begin; 
                    j = end; 
                } 
                else 
                { 
                    i = end; 
                    j = begin; 
                } 
                while (i < j) 
                { 
                    temp = array[i]; 
                    array[i] = array[j]; 
                    array[j] = temp; 
    
                    i++; 
                    j--; 
                } 
            } 
        } 
    } 
    
  31. 木野狐(Neil Chen)
    *.*.*.*
    链接

    木野狐(Neil Chen) 2009-05-27 22:22:00

    我做的办法比较笨。。

  32. 老赵
    admin
    链接

    老赵 2009-05-27 22:25:00

    @银河: 很好的文章,对初学者很有帮助。请问一下楼主,在“主体逻辑”一节中,以下一句话的中“眼力”是什么意思?那么老赵眼力最好的做法是什么呢?

    还有,在“参考答案”一节中,

    throw new ArgumentOutOfRangeException("end不能小于begin", (Exception)null); 
    

    为什么不直接使用:

    throw new ArgumentOutOfRangeException("end不能小于begin"); 
    

    谢谢!

    眼力 => 眼里,呵呵。

    ArgumentOutOfRangeException的构造函数是这样的:

    xxx(message, innerException)
    xxx(paramName)

    所以,明白原因了吧?

  33. 老赵
    admin
    链接

    老赵 2009-05-27 22:27:00

    @徐少侠: 为什么没有人考虑线程安全性?难道数组操作是线程安全的?

    没错,你考虑得更深一步,很好。

  34. 老赵
    admin
    链接

    老赵 2009-05-27 22:27:00

    @m j: 个人认为老赵的问题方法签名不够合适。。Array在这里反序白反了。。即使是用作简单的考题也应该有个输出比较好吧。。

    白反了吗?你真的试验过?你的概念可能有些模糊,array是引用传递的。

  35. 老赵
    admin
    链接

    老赵 2009-05-27 22:29:00

    @隐约有歌: 这个题目要是再出狠一点,函数的第一个参数不是 int[],而是给 Array。这样就要考虑到了数组的下界,不一定是 0 了啊,需要用 Array.GetLowerBound 来获取。数组也有可能是2维的,怎么逆转?可以考察程序员的全面思维能力。~

    这个要求就更进一步了,不过也相当于提示了别人这方面的问题。

  36. 木野狐(Neil Chen)
    *.*.*.*
    链接

    木野狐(Neil Chen) 2009-05-27 22:29:00

    发现跟老赵的答案有些不同,我把 begin..end 大小也自动交换了,似乎没有必要。。。

  37. 木野狐(Neil Chen)
    *.*.*.*
    链接

    木野狐(Neil Chen) 2009-05-27 22:31:00

    另外我遗漏了对 Array 是否为 null 的检查。呵呵

  38. 木野狐(Neil Chen)
    *.*.*.*
    链接

    木野狐(Neil Chen) 2009-05-27 22:32:00

    要做到 perfect 还是不容易哦.

  39. 老赵
    admin
    链接

    老赵 2009-05-27 22:32:00

    @隐约有歌: 尝试了下,跟你写出来的代码很类似,呵呵!

    int temp = array[end]; 
    array[begin] = temp; 
    array[end] = array[begin]; 
    

    你的交换代码有问题,呵呵。

  40. 老赵
    admin
    链接

    老赵 2009-05-27 22:32:00

    @James.Ying: 都差不多 不知道还有什么更神奇的方法不

    有人不是用递归吗?呵呵。

  41. C Ser
    *.*.*.*
    链接

    C Ser 2009-05-27 22:36:00

    少判断了一个Array为null的情况,呵呵

  42. C Ser
    *.*.*.*
    链接

    C Ser 2009-05-27 22:40:00

    static void Reverse(int[] array, int start, int end)
    {
        int length = array.Length;
        if (start < 0 || start >= length || end < 0 || end >= length)
        {
            throw new ArgumentException("Out of Range");
        }
        if (array==null)
        {
            throw new NullReferenceException();
        }
        int small = start > end ? end : start;
        int big = start > end ? start : end;
        for (int i = small, j = big; i < j; i++, j--)
        {
            array[i] = array[i] ^ array[j];
            array[j] = array[i] ^ array[j];
            array[i] = array[i] ^ array[j];
        }
    }
    

    这样玩可不可以,呵呵?null的判断是后加上的

  43. 老赵
    admin
    链接

    老赵 2009-05-27 22:41:00

    @C Ser
    不知道你是否发觉,你的array == null的判断是没有效果的?

  44. m j[未注册用户]
    *.*.*.*
    链接

    m j[未注册用户] 2009-05-27 22:42:00

    @Jeffrey Zhao: 白反了吗?你真的试验过?你的概念可能有些模糊,array是引用传递的。

    呵呵试验了。。确实是引用传递。。对数组还真是了解得不够。。

    CSDN的学生中心前几天我也去看过。。题还有点少。。当时随便做几个题也错了一个。。基础是有些问题了。。

    不过看看身边的同行们。。恐怕一个不如一个。。现在搞.Net基础扎实的真的是不多诶。。

  45. C Ser
    *.*.*.*
    链接

    C Ser 2009-05-27 22:43:00

    @Jeffrey Zhao
    呵呵 加错位置了

    判断应该扔到前面

    惭愧惭愧

  46. 老赵
    admin
    链接

    老赵 2009-05-27 22:44:00

    还是参与度高的题目受欢迎,老赵好久没有遇到这么热闹的帖子了,呵呵,多谢大家支持。

  47. 老赵
    admin
    链接

    老赵 2009-05-27 22:45:00

    @m j
    嗯,怎么说呢,基础的确重要,不过现在学生中心很多题目感觉纠结与细节了,比如哪种数组初始化方式是正确还是错误的,呵呵。

  48. 温景良(Jason)
    *.*.*.*
    链接

    温景良(Jason) 2009-05-27 22:51:00

    up

  49. 木野狐(Neil Chen)
    *.*.*.*
    链接

    木野狐(Neil Chen) 2009-05-27 22:54:00

    好题目啊。用来面试其实蛮合适的。

  50. 啊不才
    *.*.*.*
    链接

    啊不才 2009-05-27 23:01:00

    先给出我的答案再看看老赵的讲解:)

    static void Reverse(int[] array, int begin, int end)
    {
        if (begin <=0 || end >= array.Length)
        {
            throw new IndexOutOfRangeException("begin and end must be between 0 and length-1;");
        }
        if (begin > end)
        {
            throw new IndexOutOfRangeException("begin must be less or equal than end.");
        }
        while (begin < end)
        {
            Swap(ref array[begin++], ref array[end--]);
        }
    }
    
    static void Swap(ref int firstNumber, ref int secondNumber)
    {
        int temp = firstNumber;
        firstNumber = secondNumber;
        secondNumber = temp;
    }
    

    呵呵,受教了,谢谢了

  51. 银河
    *.*.*.*
    链接

    银河 2009-05-27 23:03:00

    @Jeffrey Zhao (33楼)
    明白了。
    谢谢老赵!

  52. 斯克迪亚
    *.*.*.*
    链接

    斯克迪亚 2009-05-27 23:12:00

    去CSDN那看了一眼,感觉没什么意思,像是回到学校,或是在面试,从那里虽然也能找到不足、提升技术,但是是为了提升而提升的。
    我个人认为,在信息爆炸时代,盲目将各种知识装入脑子是一种浪费行为,很多东西一眼扫过即可,你只需要知道你能干什么,而不需要记住怎么干,在真正应用时再去查找、研究也不迟,这样对你真正有用的东西你肯定会在多次使用中牢牢掌握,而没用的东西始终不会占据你的大脑存储空间,更不会浪费你的宝贵时间。
    当然,如果是研究人员或是讲师,系统而充分地了解自己的领域是绝对有必要的。

  53. 老赵
    admin
    链接

    老赵 2009-05-27 23:12:00

    @木野狐(Neil Chen): 好题目啊。用来面试其实蛮合适的。

    其实现在觉得至少“主体逻辑”大家都做得不错,为什么我在面试的时候,8成以上的人就是连反序都写不对呢?

    那时候又没有要求用纸和笔,是给笔记本编程的。

  54. 老赵
    admin
    链接

    老赵 2009-05-27 23:14:00

    @斯克迪亚
    所以我觉得,还是一些基础性的东西重要,例如编程能力,这样的能力无论对哪个方向哪个领域的人都是重要的。
    哦,对了,还有思考问题的方式,分析问题的能力。这些都属于“基本素质”。

  55. guojing
    *.*.*.*
    链接

    guojing 2009-05-27 23:21:00

    static int[] Reverse(int[] list, int startIndex, int endIndex)
    {
        int[] lists = list;
        int temp;
    
        if (startIndex < 0)
        {
            throw new Exception("开始索引小于数组最小值", null as Exception);
        }
    
        if (endIndex > lists.Length)
        {
            throw new Exception("开始索引大于数组最大值", null as Exception);
        }
    
        if (endIndex != startIndex)
        {
            while (startIndex <= endIndex)
            {
                temp = lists[startIndex];
                lists[startIndex] = lists[endIndex];
                lists[endIndex] = temp;
                startIndex++;
                endIndex--;
            }
        }
    
        return lists;
    }
    

    不过我在主函数里面还是有提示输入和输出的,至少在自己写的时候还是可以看到结果的。。今天看到你的twitter上的更新,过来看看。。:)

  56. guojing
    *.*.*.*
    链接

    guojing 2009-05-27 23:28:00

    另外,我不知道这样去做异常了是不是真的好,我觉得另一个做法是可以写一个静态类,有些异常可以捕获,有些异常就让他直接抛出,有些异常就不用管,这样也挺好的。。比如微软就有这种做法。。

    internal static class CriticalExceptions
    {
        internal static bool IsCriticalException(Exception ex)
        {
            return ex is NullReferenceException ||
                ex is StackOverflowException ||
                ex is OutOfMemoryException ||
                ex is System.Threading.ThreadAbortException ||
                ex is System.Runtime.InteropServices.SEHException ||
                ex is System.Security.SecurityException;
        }
    }
    

    不才,互相探讨 :)

  57. 枝上又闻啼[未注册用户]
    *.*.*.*
    链接

    枝上又闻啼[未注册用户] 2009-05-27 23:37:00

    static void Reverse(int[] array, int begin, int end) 
    { 
        while (end > begin) 
        { 
            int temp = array[begin]; 
            array[begin] = array[end]; 
            array[end] = temp; 
    
            begin++; 
            end--; 
        } 
    } 
    

    数组第一个中第一个数是array[0] 所以我觉得应该begin 和end 都应该减1。

    不然从1到3交换 数组中就是从2到4交换的

  58. 老赵
    admin
    链接

    老赵 2009-05-27 23:39:00

    @guojing
    抛出归抛出,处理归处理,你这是异常的处理方式,而我这里是异常的抛出啊。
    异常是接口设计的一部分。

  59. 老赵
    admin
    链接

    老赵 2009-05-27 23:40:00

    @枝上又闻啼
    begin和end都是0-based的下标,这个应该是默认的标准吧。

  60. guojing
    *.*.*.*
    链接

    guojing 2009-05-27 23:56:00

    @Jeffrey Zhao
    嗯。很有道理,不过我觉得有时候是差不多的,比如我设计一个类的时候,就不喜欢把异常直接放到代码块中。。

  61. 阿巍
    *.*.*.*
    链接

    阿巍 2009-05-28 00:03:00

    static void Reverse(int[] array,int begin,int end) { 
        int number = (end - begin + 1) / 2; 
        int temp = 0; 
        for (int i = 0; i <= number - i; i++ ) { 
            temp = array[begin-1 + i]; 
            array[begin-1 + i] = array[end-1 - i]; 
            array[end-1 - i] = temp; 
    

    笨了点。。。。

  62. 骆明亮
    *.*.*.*
    链接

    骆明亮 2009-05-28 01:01:00

    老赵减肥成功。

  63. 陈 亮
    *.*.*.*
    链接

    陈 亮 2009-05-28 01:13:00

    我写的和LZ 一样的. 就是少判断了异常

  64. volnet(可以叫我大V)
    *.*.*.*
    链接

    volnet(可以叫我大V) 2009-05-28 03:32:00

    支持一下,.NET社区的人比别人偷懒,因为大家都太拿来主义了,要向老赵学习深入浅出。微软给你那些不是为了让你坐享其成,而是抛砖引玉呢~ 最近面试了一些人,嗯,不能说职位好坏,但起码他们给简历的时候表示自己很牛。七八年工作经验的比比皆是,项目十几个的不在话下,海龟也有。 但很遗憾,问了半天,连页面传值都搞不清楚,Response.Redirect居然和windows.open相同?所以不管用多少长篇大论来描述那些辉煌的项目经历,我都不太认同他们的编程之路,当然要混到饭吃肯定是没问题的,而且比我混的好的肯定更多,但真正适合的凤毛麟角。 已经都只问最基本的,最入门的,随便买本书翻开第一页就讲了的问题,所以还是希望大家都不要浮躁。更不要以为工作年限==工作经验!

  65. 随处走走
    *.*.*.*
    链接

    随处走走 2009-05-28 08:13:00

    做出来了,但写的太复杂了...多学习

  66. eaglet
    *.*.*.*
    链接

    eaglet 2009-05-28 08:27:00

    static void Reverse(int[] array, int begin, int end) 
    

    这个静态函数被声明为私有的而不是Public 或者 Internal。我觉得对于私有函数,判断参数合法性用断言似乎比直接判断要好,否则如果这个函数被上层函数循环调用,那么每次循环都要发生4次判断,如果循环100万次,则判断400万次。如果把这个判断放在上层函数中,只需要判断一次就可以了。

    如下面代码

    static void MyFunction()
    {
        for (int i = 0; i < 1000000; i++)
        {
            int[] array = new int[10000];
    
            //Init array in here
            //......
    
            Reverse(array, 0, array.Length - 1);
    
            //Process array after reverse in here
            //......
        }
    }
    

    在这个调用代码中,参数的合法性实际上已经保证了,如果在Reverse函数中再进行判断,则进行400万次多余的判断。

    下面是采用断言的Reverse函数,老赵可以在Release 版本中比较一下采用断言和直接判断并抛出异常两种函数在上述应用中的效率。

    static void Reverse(int[] array, int begin, int end)
    {
        Debug.Assert(array != null);
        Debug.Assert(begin >= 0 && end >= begin && end < array.Length);
    
        while (end > begin)
        {
            int temp = array[begin];
            array[begin] = array[end];
            array[end] = temp;
    
            begin++;
            end--;
        }
    }
    

    当然如果Reverse声明称Public,我觉得判断并抛出异常会好一些,因为这个函数既然提供给外部调用,我们无法控制外部函数做参数判断。

  67. dreamskyyu
    *.*.*.*
    链接

    dreamskyyu 2009-05-28 08:37:00

    老赵有空天天写,我天天来学习,永不间断!

  68. 隐约有歌
    *.*.*.*
    链接

    隐约有歌 2009-05-28 10:22:00

    @Jeffrey Zhao: 你的交换代码有问题,呵呵。

    的确有问题,呵!写出来的代码没有经过测试,就会这么有问题啊!

    int temp = array[end];
    array[end] = array[begin];
    array[begin] = temp;
    

    我写的代码中,第三个 if 检查应该是针对 end 的,抛出的错误是 end 越界。结果写昏了头,if 条件里面是检查 begin。应该更正。

    惭愧了阿~!

    面试的时候,写完代码后一定要测试,即使是最简单的案例,也能排出很多低级错误。

  69. 隐约有歌
    *.*.*.*
    链接

    隐约有歌 2009-05-28 10:26:00

    这个题目可以引申下。

    为了交换两个 int,我们用到了一个临时变量 temp。可否不使用临时变量,来交换两个 int?

    尝试了下:

    array[end] = array[begin] + array[end];
    array[begin] = array[end] - array[begin];
    array[end] = array[end] - array[begin];
    
  70. 隐约有歌
    *.*.*.*
    链接

    隐约有歌 2009-05-28 10:31:00

    @eaglet: 这个静态函数被声明为私有的而不是Public 或者 Internal。我觉得对于私有函数,判断参数合法性用断言似乎比直接判断要好。

    同意这一点。我写代码的习惯也是如此!私有的函数只是断言,公开的函数才抛出异常。:)

  71. Jeffrey Chan
    *.*.*.*
    链接

    Jeffrey Chan 2009-05-28 10:47:00

    这道题kill了多少人呀!如果再走楼梯的来做,更多人会被kill了。

  72. --简单[未注册用户]
    *.*.*.*
    链接

    --简单[未注册用户] 2009-05-28 11:12:00

    没啥意思,不知道楼主想说明啥,如果只是考一下算法,我觉得有些过了,
    如果真是写实际项目中的方法,相信绝大部分人都会做越界判断的

  73. yearN
    *.*.*.*
    链接

    yearN 2009-05-28 11:28:00

    菜鸟也凑一下热闹,写一下我的想法:

    if(array.Length<=begin || array.Length>=end || begin<0 || end<=begin) 
    { 
        throw new Exception("..."); 
    } 
    
    int temp; 
    for(int i=0;i<=(end-begin)/2;i++) 
    { 
        temp=array[i+begin]; 
        array[i+begin]=array[end-i]; 
        array[end-i]=temp; 
    } 
    
  74. 阿水
    *.*.*.*
    链接

    阿水 2009-05-28 11:51:00

    哎 不明白这个题到底考什么? 到底有几个知识点?
    反正我没看明白,如果只是交换变量的话,好像
    程序设计最早就是学这儿吧!
    还是没明白,为什么那么多人说这个题好!!!!
    哈哈 或者我太菜

  75. 高歌
    *.*.*.*
    链接

    高歌 2009-05-28 11:59:00

    和cnblogs比,CSDN确实是菜地啊

    看了回帖又学了不少

  76. Kevin Dai
    *.*.*.*
    链接

    Kevin Dai 2009-05-28 12:28:00

    array == null
    begin < 0;
    end < begin
    end >= array.Length
    

    看了老赵的这个分析,就明白我的参数验证的不严密性了。虽然我的也验证完全了,情况都考虑到了。但是还是有点冗余。

    我还是喜欢用++i,不喜欢用i++,呵呵

  77. 老赵
    admin
    链接

    老赵 2009-05-28 13:03:00

    @eaglet
    断言就是Release里就不执行了,这个我明白阿,呵呵。
    嗯,看来我下次还是标明public吧。
    其实这就是个练习,“要求”对参数输入进行验证。
    就好比某道题目要求不许用递归解决某问题,求的就是练习,而不是真正在实际中怎么怎么,呵呵。

  78. 老赵
    admin
    链接

    老赵 2009-05-28 13:04:00

    @阿水: 哎 不明白这个题到底考什么? 到底有几个知识点?反正我没看明白,如果只是交换变量的话,好像程序设计最早就是学这儿吧!还是没明白,为什么那么多人说这个题好!!!!哈哈,或者我太菜

    你是不是没有看后面的解答?

  79. 老赵
    admin
    链接

    老赵 2009-05-28 13:07:00

    @简单: 没啥意思,不知道楼主想说明啥,如果只是考一下算法,我觉得有些过了, 如果真是写实际项目中的方法,相信绝大部分人都会做越界判断的

    嗯,是啊,人人都会写,但是写不对呢。这题就是个简单的问题,看看是否考虑周全。

    我觉得吧,说“实际项目中我做得对,练习题就不一定”,和说“我理论不行,做应用不错”是一个性质,我不认同。

  80. 老赵
    admin
    链接

    老赵 2009-05-28 13:08:00

    @Jeffrey Chan: 这道题kill了多少人呀!如果再走楼梯的来做,更多人会被kill了。

    走楼梯没有考察的意思,知道就知道,不知道就不知道。

  81. 老赵
    admin
    链接

    老赵 2009-05-28 13:09:00

    @隐约有歌: 这个题目可以引申下。

    为了交换两个 int,我们用到了一个临时变量 temp。可否不使用临时变量,来交换两个 int?

    尝试了下:

    array[end] = array[begin] + array[end];
    array[begin] = array[end] - array[begin];
    array[end] = array[end] - array[begin];
    

    这就是纯粹的“游戏”了阿,我觉得价值不大。而且说起来还可以用异或,你这个做法——万一有checked,越界了咋办?呵呵

  82. 老赵
    admin
    链接

    老赵 2009-05-28 13:10:00

    @dreamskyyu: 老赵有空天天写,我天天来学习,永不间断!

    不好意思,一般来说……没空的……

  83. 老赵
    admin
    链接

    老赵 2009-05-28 13:12:00

    @volnet(可以叫我大V): 所以还是希望大家都不要浮躁。更不要以为工作年限==工作经验!

    我看出来了,你太讽刺某人了。

  84. eaglet
    *.*.*.*
    链接

    eaglet 2009-05-28 15:03:00

    @老赵: 这就是纯粹的“游戏”了阿,我觉得价值不大。而且说起来还可以用异或,你这个做法——万一有checked,越界了咋办?呵呵

    当初上研究生时,教算法老师就拿这个来考我们,被我当场用异或解决,他说用异或不好要用加减,我当场就问他越界怎么考虑,他说我思想太复杂,考虑太多,我晕倒。中国的教育是不是什么问题就只能有一个标准答案?

  85. 隐约有歌
    *.*.*.*
    链接

    隐约有歌 2009-05-28 15:24:00

    @老赵: 这就是纯粹的“游戏”了阿,我觉得价值不大。而且说起来还可以用异或,你这个做法——万一有checked,越界了咋办?呵呵

    越界了依然也能得到正确的结果。 在执行加法的时候,若是整数上溢出的话,正的会变成负的,那么在减的时候,也会发生下溢出,这样就能得回原来的数字了。

    比如代码:

    unchecked {
        int i = Int32.MaxValue;
        int j = Int32.MaxValue - 1;
    
        Console.WriteLine("{0} {1}", i, j);
    
        j = i + j;
        i = j - i;
        j = j - i;
    
        Console.WriteLine("{0} {1}", i, j);
    }
    

    打印的结果便是:

    2147483647 2147483646
    2147483646 2147483647

    还有,这怎么是游戏了呢? 把额外内存的需求从 O(1) 减少到了 O(0), 难道不是进步么? 对于内存紧张的设备而言,这样的钻研是必要的阿!

  86. 老赵
    admin
    链接

    老赵 2009-05-28 15:28:00

    @隐约有歌
    这个我知道,我是说,如果checked怎么办? 至少你必须写成unchecked { ... }。
    我的本意是“编程”,不是要让别人把注意力集中在这些地方,这种只是些小技巧。
    而且这样的问题,一搜都知道,不觉得有什么意义。

  87. 老赵
    admin
    链接

    老赵 2009-05-28 15:31:00

    @隐约有歌
    这样的进步,是以程序的清晰性为代价的,如此“过早优化”,不可不谓“万恶之源”。
    make clear program fast远比make fast program clear容易。
    就算内存紧张的设备,在优化到这里之前还有太多方式可以优化,要知道这里也就优化了一个字长。
    还有,你真的确定这么做会节省资源?程序和最终汇编结果不是这么对应的。
    就好比你这里看到说好像没有开额外变量,但是汇编呢?说不定它还是会把元素读入寄存器,然后计算,然后写回。
    因此,就算在资源紧张的设备上,内存优化的关键也在于数据结构的重新设计,而不是这方面的吹毛求疵。

    再者,我更希望用一个标准的swap来写——我倒情愿让编译器来帮我优化。
    否则你程序要负责的东西太多了,例如,你是否要在代码里内联一些子过程?
    我还情愿把Swap逻辑独立抽出成一个方法呢。

    所以我说,这么做没有什么必要,当作智力题固然不错。要说编程题……

  88. eaglet
    *.*.*.*
    链接

    eaglet 2009-05-28 15:33:00

    老赵的意思是 万一有checked
    据我所知有些硬件如果整数运算溢出是会出硬件中断的,有的会截断,不同硬件处理是不一样的。只是windows 通常是跑在Intel 兼容的硬件上,侥幸没有这个问题。
    另外clr 会不会在某些条件下检查整数溢出呢?比如跑在一些特殊的硬件下。

  89. 老赵
    admin
    链接

    老赵 2009-05-28 15:37:00

    @eaglet
    应该不会,因为checked/unchecked是显式定义的要求,因此就算在不同的系统架构或硬件上,结果应该一样,否则这个“虚拟机”就失去意义了。
    就好比CLR把x86,IA64等架构的Memory Model的“效果”都统一了,让程序员开发出来的托管程序运行结果在哪里都一致。

  90. winter-cn
    *.*.*.*
    链接

    winter-cn 2009-05-28 17:16:00

    难道没有人用那个欠揍型的swap?

    a^=b;
    b^=a;
    a^=b;

  91. 混世者
    *.*.*.*
    链接

    混世者 2009-05-28 18:11:00

    过于刻板,只是编程题,重在思路和代码的优化性,你这么强调完整和全面性,需要别人跟你的思路一摸一样,这完全是哗众取宠,要知道,如果把所有的意外和特殊性都考虑进去,这就不是编程题所关注的核心了!

  92. funny zak
    *.*.*.*
    链接

    funny zak 2009-05-28 18:40:00

    先前错了改正下

    using System; 
    using System.Collections.Generic; 
    
    public class MyClass 
    { 
        public static void Main() 
        { 
            int[] array = new int[]{1,3,4,6,9,333,23,0,2,23,22}; 
            Reverse(array,1,8); 
        } 
    
        static void Reverse(int[] array, int begin, int end) 
        { 
            if (!(array.Length < 2 || end < begin || begin < 0 || end < 0 || begin == end || begin > array.Length || end > array.Length)) 
            { 
                int count = end/2 + begin/2; 
                for (int i = 0; i < count; i++) 
                { 
                    int temp = array[end]; 
                    array[end] = array[begin]; 
                    array[begin] = temp; 
                    ++begin; 
                    --end; 
                } 
                string strarry = string.Empty; 
                foreach (int one in array) 
                { 
                    strarry += one.ToString()+" "; 
                } 
                Console.WriteLine(strarry); 
    
            } 
            else 
            { 
                Console.WriteLine("error array"); 
            } 
            Console.ReadLine(); 
        } 
    }
    
  93. 郑明
    *.*.*.*
    链接

    郑明 2009-05-28 18:42:00

    public static void Reverse(int[] array, int begin, int end) { 
    
        int m=(end-begin)/2; 
        for(int i=begin,j=end;i<= m && j>= m ;i++,j--) 
        { 
            if(array[i]!=array[j])//不相等 
            { 
                Swap(array, i, j); 
            } 
        } 
    } 
    
    static void Swap(int[] array, int begin, int end) 
    { 
        int temp = array[begin]; 
        array[begin]= array[end]; 
        array[end]= temp; 
    }
    
  94. 老赵
    admin
    链接

    老赵 2009-05-28 20:06:00

    @混世者: 过于刻板,只是编程题,重在思路和代码的优化性,你这么强调完整和全面性,需要别人跟你的思路一摸一样,这完全是哗众取宠,要知道,如果把所有的意外和特殊性都考虑进去,这就不是编程题所关注的核心了!

    我无所谓别人用什么思路。结果正确就可以了,我的文章只是给了我的解题思路而已。

    考虑所有的意外和特殊性也是编程的一部分,就好比做数学题一样。思考完整,为什么不属于编程的核心?简单的问题都思考不完整,算不上优秀的程序员。

  95. 老赵
    admin
    链接

    老赵 2009-05-28 20:08:00

    @funny zak
    还是错了啊,看看文章内容吧。

  96. 水果阿生
    *.*.*.*
    链接

    水果阿生 2009-05-28 20:29:00

    @Jeffrey Zhao: 我看出来了,你太讽刺某人了。

    太恶毒了,这话的程度赶上我了。对了,老赵,上海话的“小开”什么意思?

  97. 老赵
    admin
    链接

    老赵 2009-05-28 20:42:00

    @水果阿生
    下面是老赵搜索出来的,也增长见识了啊,以前以为就是富家子弟的意思。

    http://ask.koubei.com/question/1406120826836.html
    “小开”一语,是沪语最大的创举,这句上海“闲话”已成绝版了!
    “小开”比“公子”多了点俗气,也多了几分诙谐;很有种不以为然的海派作风。
    “小开”十分神髓地描绘出这样一簇上海男人:一般没有自己独立打理的一爿生意或赖以作主要生活来源的专业,只恃着老爸或老家的财势,却一样过得鲜亮风光;因为是小开,凡事不知轻重,不分尊卑,喜招摇过市……因为有的是时间和铜钿,小开棋琴诗画,跳舞桥牌沙蟹麻将网球玩票,都知一点,又因为天生懒散,大都是三脚猫。
    小开绝不能与花花公子、二世祖和洋场恶少划等号。
    小开对上海最大的贡献,是拓展消费文化和缔造海派时尚。小开在上海男人队列中,比例不小。若写上海男人而剔除小开一族,上海男人的特色会大打折扣,犹如吃小笼包少了一碟浸着姜丝的醋,炖鸡汤少了几片火腿;上海滩的红尘俗画,如果没有小开,会少好多神韵!
    参考资料:上海方言的绝版:小开 http://www.sina.com.cn 2002/04/19 14:45 解放日报

  98. 徐少侠
    *.*.*.*
    链接

    徐少侠 2009-05-28 20:51:00

    @水果阿生
    貌似小开是指大老板的少爷

    泛指生活悠闲富有,爱玩爱出风头的年轻人

  99. joywen
    *.*.*.*
    链接

    joywen 2009-05-28 21:44:00

    偶犯错误了

  100. xiongli lixiong[未注册用户…
    *.*.*.*
    链接

    xiongli lixiong[未注册用户] 2009-05-28 23:29:00

    static void Reverse(int[] array, int begin, int end) 
    { 
        while(begin<end) 
        { 
            swap(array[beg],array[end]); 
            begin++; 
            end--; 
        } 
    } 
    

    至于exception, CLR会自己给我抛的

  101. xiongli lixiong[未注册用户…
    *.*.*.*
    链接

    xiongli lixiong[未注册用户] 2009-05-28 23:33:00

    嘿嘿,果然做对了
    我觉得, 参数判断什么的就不用了。原因嘛,可以参考CLR类库的实现。 不然还mutiple threading呢。。。。

    话说,这种题目才是看真功夫的。

  102. 老赵
    admin
    链接

    老赵 2009-05-28 23:33:00

    @xiongli lixiong
    但是抛出来的Exception不对,提供信息也不准确不正确。
    比如应该是ArgumentNullException,你的写法就会抛NullReferenceException。
    这样做的话,API设计的就不好了。
    看看MSDN里的API,抛出哪些异常是这个API设计的一部分。
    再看看.NET类库里的代码,该怎么抛都是经过设计,而不是随意让人抛出的。

  103. 老赵
    admin
    链接

    老赵 2009-05-28 23:36:00

    @xiongli lixiong
    CLR类库的实现可是会判断参数的哟,微软.NET框架设计者写的Framework Design Guidelines里也写的很清楚了。
    至于多线程就需要标明了,就好比你去看MSDN都会看到类似的话:“XXX不保证线程安全”。
    其实这道题目太简单,真功夫还是看对于参数的校验,主题逻辑过于简单了,呵呵。

  104. xiongli lixiong[未注册用户…
    *.*.*.*
    链接

    xiongli lixiong[未注册用户] 2009-05-28 23:40:00

    你说的throwAugNullExcep是对的。 其实如果打开fxcop,这里如果不判断, fxcop都会报错。 不过我们写test代码就没有这么严格

    不过要萃毛球吃的话, 标准代码还是有鸡蛋里面挑骨头的地方,比如:

    static void Reverse(int[] array, int begin, int end) 
    {
        // 这里的错误信息应该从resource里面读,否则无法本地化
        if (null == array) 
        { 
            throw new ArgumentNullException("array", "parameter array can't be null"); 
        } 
    
        // begin=-1, array.length=0的时候, 打印出来的是must range from 0 to -1, 不好看吧? 
        if (begin > array.Length || begin < 0 ) 
        { 
            throw new ArgumentOutOfRangeException("begin", "parameter begin must range from 0 to " + (array.Length - 1).ToString()); 
        }
    
        if ( end > array.Length || end < 0) 
        { 
            throw new ArgumentOutOfRangeException("end", "parameter end must range from 0 to " + (array.Length - 1).ToString()); 
        } 
    
        if (end < begin) 
        { 
            throw new ArgumentException("parameter end must be greater equal than parameter begin", "end"); 
        } 
    
        int i = begin, j = end,temp; 
        // 没有必要用i,j吧。。。。。。 
    
        while (i < j) 
        { 
            temp = array[i]; 
            array[i] = array[j]; 
            array[j] = temp; 
            ++i; --j; 
        }
    }
    
  105. xiongli lixiong[未注册用户…
    *.*.*.*
    链接

    xiongli lixiong[未注册用户] 2009-05-28 23:43:00

    当然, 另外要指出的是, 这个函数签名里面没有public
    给我的直觉是不需要错误检查。
    错误检查应该是public函数里面检查好, 也就是这个函数的caller负责

  106. 老赵
    admin
    链接

    老赵 2009-05-28 23:44:00

    @xiongli lixiong: 当然, 另外要指出的是, 这个函数签名里面没有public,给我的直觉是不需要错误检查。错误检查应该是public函数里面检查好,也就是这个函数的caller负责

    嗯嗯,下次一定加上public。对于非public方法,还是使用Assert比较合适,这样在Release Build中就不会出现校验了。

  107. 老赵
    admin
    链接

    老赵 2009-05-28 23:45:00

    @xiongli lixiong
    你说的没错,例如文字应该从资源文件里读,这些都是真正写类库的时候需要遵守的要求。

  108. xiongli lixiong[未注册用户…
    *.*.*.*
    链接

    xiongli lixiong[未注册用户] 2009-05-28 23:46:00

    我靠,回头看别人的回贴,好长好长啊。。。。。。

  109. xiongli lixiong[未注册用户…
    *.*.*.*
    链接

    xiongli lixiong[未注册用户] 2009-05-28 23:50:00

    我一般给人的面试题目是,抽取字符串

    给定字符串A, B, C

    然后在A里面读取位于B,C中间的返回

    比如
    A="AAABBBCCCDDD"
    B="BBB"
    C="DDD"

    然后返回CCC

    从来没有人能够在我手里pass过

  110. 老赵
    admin
    链接

    老赵 2009-05-28 23:52:00

    @xiongli lixiong
    似乎也不难(似乎会有点烦,而且需要仔细)。难点在什么地方?能用IndexOf吗?估计大部分面试者都在偏移量计算上落马吧……
    是否要求面试者“追问”说“B是否一定要在C前面?”,“是否需要返回所有结果”?
    有些面试题也会考察一个人对问题思考是否完整等等,期望面试者能够“补充提问”——也是在微软得知的做法。

  111. xiongli lixiong[未注册用户…
    *.*.*.*
    链接

    xiongli lixiong[未注册用户] 2009-05-29 00:02:00

    就算写代码的时候你可以使用一些假设, 但是中间需要的基本编程技巧比如indexof, 下标计算, 输入值检查都会考察到

    写完代码,会让写测试用例,这个时候那些

    “B是否一定要在C前面?”,“是否需要返回所有结果”?

    一个都逃不掉。。。。。。所以这里可以考察和代码结合的逻辑推导严密性

  112. 老赵
    admin
    链接

    老赵 2009-05-29 00:07:00

    @xiongli lixiong
    那真很难过了,你看我这个问题已经筛掉90%的人了啊。

  113. xiongli lixiong[未注册用户…
    *.*.*.*
    链接

    xiongli lixiong[未注册用户] 2009-05-29 00:16:00

    我那个题目有经验的工程师肯定能过的,至少95%没问题
    其实这个题目对结果的要求也不高
    对于常见的情况代码没有问题
    特别的情况考虑到1/2就可以了

  114. _龙猫
    *.*.*.*
    链接

    _龙猫 2009-05-29 09:03:00

    一群人好好的端午节不去吃粽子在这里吹水。
    看完让我很想回去把《数据结构》再学一遍

  115. skyaspnet
    *.*.*.*
    链接

    skyaspnet 2009-05-29 10:05:00

    您好,刚看了CSDN学生中心,觉得UCenter Home 1.5这个PHP产品做得非常好,个人感觉.NET开发的一些网站速度方面都不是太理想,很少见您对这方面进行点评,希望您能抽时间点评一下主流的网站开发技术,让我们这些菜鸟多开眼界,学到更多东西,非常感谢!

  116. skyaspnet
    *.*.*.*
    链接

    skyaspnet 2009-05-29 10:10:00

    另外我看到MSN的中文门户网站是用JSP开发的,感觉挺奇怪的,MSN按理来说应该是会用ASP.NET开发的,呵呵,没理解

  117. 老赵
    admin
    链接

    老赵 2009-05-29 13:50:00

    @skyaspnet
    可以负责地说,.NET代码的运行效率比PHP高多了,嗯,也比Ruby,Python高多了,也比Java高。
    但是,一个网站性能的关键不在语言平台,而在于你做的怎么样。.NET写的不好,照样性能很差。Python用的好,照样有Google的速度。这些都不是网站性能的瓶颈。
    至于MSN,是微软给外包公司的,还是合作关系什么的,不是微软作的,不用ASP.NET也很正常。

  118. 老赵
    admin
    链接

    老赵 2009-05-29 13:56:00

    @_龙猫: 一群人好好的端午节不去吃粽子在这里吹水。看完让我很想回去把《数据结构》再学一遍

    其实只是编程能力,谈不上数据结构,当然数据结构肯定是重要的。

  119. skyaspnet
    *.*.*.*
    链接

    skyaspnet 2009-05-29 16:21:00

    @Jeffrey Zhao
    感谢您的回答,但是我经常在CSDN和一些网站上看到这样的讨论,而且基本上都是清一色地觉得PHP速度快,所以会有疑问,到底是操作系统的平台问题呢?还是WEB服务器的性能呢?看到全球50大网站所使用的WEB服务器,清一色是APACHE,只有MS的是IIS,难道仅仅只是考虑到成本?所以还是希望您能抽时间发篇讲解的文章,也可以让很多不明白真相的朋友能够减少这方面的争论,呵呵,只是个建议,您的文章大家比较相信,如果有时间的话不妨为我们广大菜鸟解惑,谢谢:)

  120. 老赵
    admin
    链接

    老赵 2009-05-29 16:58:00

    @skyaspnet
    iis性能不差,.net性能不差,windows性能不差,差是好多年前的事情了。
    .net因为入门容易,导致许多糟糕项目诞生,性能差不是.net的问题。
    至于前50大网站都是用apache我不相信,不知道你的数据是哪里来的呢?
    别的不知道,至少ebay有一部分windows,myspace和microsoft都是全部windows。
    apache现在用的越来越少了阿,因为比较“重”,都有一些轻量级web服务器比如nginx慢慢流行开来了。世界上不只IIS和Apache两个种web服务器。

    有时间的话我会写得,但是我不指望别人的感觉有所改变。因为叫嚷着.net性能差的人,有没有真正了解过.net?没有真正了解就在嚷嚷,这样的办事态度说明这个人不靠谱。
    对于一个不靠谱的人,我用靠谱的方法就能让他改变观点吗?
    “民科”是学不会真正的科学的。

  121. skyaspnet
    *.*.*.*
    链接

    skyaspnet 2009-05-29 17:15:00

    @Jeffrey Zhao
    刚上CSDN找了一下原文链接,因为有一年多了,一下没找着,听您的点评,我对.NET更有信心了,非常感谢您的回复,谢谢!祝工作顺利!

  122. clayman
    *.*.*.*
    链接

    clayman 2009-05-30 05:10:00

    刚做了个测试,临时变量的方法生成的代码让我稍微有点意外,每一步都有越界检查:

    int temp = array[begin]; 
        00000010 cmp edx,esi 
        00000012 jae 00000035 
        00000014 mov ebx,dword ptr [ecx+edx*4+8] 
    
    array[begin] = array[end]; 
        00000018 cmp edi,esi 
        0000001a jae 00000035 
        0000001c mov eax,dword ptr [ecx+edi*4+8] 
        00000020 mov dword ptr [ecx+edx*4+8],eax 
    
    array[end] = temp; 
        00000024 mov dword ptr [ecx+edi*4+8],ebx 
    

    加法:

    array[j] = array[i] + array[j]; 
        0000000d mov eax,dword ptr [ecx+edx*4+8] 
        00000015 add eax,dword ptr [ecx+edi*4+8] 
        00000019 mov dword ptr [ecx+edi*4+8],eax 
    
    array[i] = array[j] - array[i]; 
        0000001d mov eax,dword ptr [ecx+edi*4+8] 
        00000021 sub eax,dword ptr [ecx+edx*4+8] 
        00000025 mov dword ptr [ecx+edx*4+8],eax 
    
    array[j] = array[j] - array[i]; 
        00000029 mov eax,dword ptr [ecx+edi*4+8] 
        0000002d sub eax,dword ptr [ecx+edx*4+8] 
        00000031 mov dword ptr [ecx+edi*4+8],eax
    
  123. 老赵
    admin
    链接

    老赵 2009-05-30 05:12:00

    @clayman
    说明你的默认编译选项中把checked打开了。

  124. clayman
    *.*.*.*
    链接

    clayman 2009-05-30 16:05:00

    @Jeffrey Zhao
    不是checked的原因,代码已经显式标记为了unchecked,并且是优化过的release版本

  125. 水手123[未注册用户]
    *.*.*.*
    链接

    水手123[未注册用户] 2009-05-31 18:03:00

    老赵的代码很优雅。

    但我有点小建议,就是不要在方法内部直接改变参数的值,除非方法的本意是这样。个人认为这是一个不好的习惯,有时这样做会造成意料之外的附作用。

    如:begin 和 end 的使用,可以改成这样:

    public static void Reverse(int[] array, int begin, int end) 
    { 
        int b=begin; 
        int e=end; 
        while (e> b) 
        { 
            int temp = array[b]; 
            array[b] = array[e]; 
            array[e] = temp; 
    
            b++; 
            e--; 
        } 
    } 
    
  126. mfkdsapfudsaiofjdsa[未注册用户…
    *.*.*.*
    链接

    mfkdsapfudsaiofjdsa[未注册用户] 2009-05-31 21:39:00

    他思维精密吗?
    他拿着他那个玩个几年的题目
    来玩学生
    再说题目是他出的
    你去网上去搜个难的
    容易出问题的题
    你好玩玩
    你知道答案
    让他去做做
    看他会不会出错

  127. 老赵
    admin
    链接

    老赵 2009-05-31 21:45:00

    @mfkdsapfudsaiofjdsa
    也就你总是想着非要把水平分个高下,别人做错了非要也让我也错一次。
    对又如何?错又如何?我可没有你那么狭隘,我是为了大家共同提高。

  128. mfkdsapfudsaiofjdsa1[未注册用户…
    *.*.*.*
    链接

    mfkdsapfudsaiofjdsa1[未注册用户] 2009-05-31 21:46:00

    赵老师
    说来说好像有点在吹你的C的数组反序函数
    个人认为
    C语言不要学的太深
    学的深了也没有用
    你的C的数组反序函数算法再好
    有sun公司的java里面类库里面封装好的数组反序好吗
    就算一样好
    傻子才会自己写

    C语言你会个数组反序好不好没什么了不起的吧

  129. 老赵
    admin
    链接

    老赵 2009-05-31 22:10:00

    @mfkdsapfudsaiofjdsa1
    没有C语言,是任何语言实现都可以,这意味着什么呢?
    这是个练习,文章标题就是“编程题”,不是为了多大的实用意义。
    就像学数学的时候解二元一次方程组。
    你解的有计算机快,有计算机好吗?
    老师讲解这个是为了吹嘘自己的“数学水平高”?
    科技发展已经那么好了,还不是每个人要从基础学起?
    真不知道你的想法为什么如此偏激,如此古怪。

  130. DiggingDeeply
    *.*.*.*
    链接

    DiggingDeeply 2009-05-31 22:21:00

    献丑了

    static void ReverseArray(int[] array, int begin, int end) 
    { 
        if (array == null || array.Length == 0) return; 
        if (begin < 0) return; 
        if (end >= array.Length) return; 
        if (begin >= end) return; 
        unsafe 
        { 
            fixed (int* ptr = &array[0]) 
            { 
                int* ptrBegin = ptr + begin; 
                int* ptrEnd = ptr + end; 
                lock (array) 
                { 
                    for (; ptrBegin < ptrEnd; ptrBegin++, ptrEnd--) 
                    { 
                        *ptrBegin ^= *ptrEnd; 
                        *ptrEnd ^= *ptrBegin; 
                        *ptrBegin ^= *ptrEnd; 
                    } 
                } 
            } 
        } 
    }
    
  131. QQTest[未注册用户]
    *.*.*.*
    链接

    QQTest[未注册用户] 2009-06-01 09:34:00

    第一感觉是对确定空间内的结果排序(其实已经大错特措了)。。。。

  132. QQTest[未注册用户]
    *.*.*.*
    链接

    QQTest[未注册用户] 2009-06-01 09:36:00

    第一感觉是对确定空间内的结果排序(其实已经大错特措了)。。。。

    结果看答案居然还可以O的!!!!!!

    。。。。。。恍然大悟阿

  133. kkun
    *.*.*.*
    链接

    kkun 2009-06-01 17:05:00

    做过赵老师的这道题...看答案去了

  134. JimLiu
    *.*.*.*
    链接

    JimLiu 2009-06-02 12:33:00

    我的观点:
    异常设计属于API设计中的一部分,这一点Java发挥的非常彻底,因为方法声明的时候就要声明好方法会抛出什么样的类型。其实我讨厌这一点,因为Java有“强制”处理异常的习惯,而我不喜欢,有时候我喜欢让异常向上传递。C#这里自由了,但是却给人造成了异常无用论的假象。
    其实结构和异常处理是高级语言中很重要的一部分,也是类库设计的重要部分,不然MSDN和Java API还花那么多篇幅来标记每个方法可能抛出的异常?
    在我自己的项目中我通常会自己写几种异常,继承一个我的异常基类。这样用于区分FCL抛出的异常和我的代码抛出的异常:比如FCL抛出异常我会做日志,然后提示;而我的异常就只是做友好化提示就好。

  135. gaoxing[未注册用户]
    *.*.*.*
    链接

    gaoxing[未注册用户] 2009-06-02 15:25:00

    唉,想得太少了

  136. 危亭
    *.*.*.*
    链接

    危亭 2009-06-05 13:23:00

    先发段代码,参与参与,哈哈!!

    private static void Reverse(int[] array, int begin, int end) 
    { 
        if (array == null)
        {
            throw new ArgumentNullException("array");
        }
    
        if (begin < array.GetLowerBound(0))
        {
            throw new ArgumentOutOfRangeException("begin");
        } 
    
        if (end > array.GetUpperBound(0))
        {
            throw new ArgumentOutOfRangeException("end");
        }
    
        if (begin > end)
        {
            throw new Exception("The value assigned to end must be not less than begin.");
        } 
    
        int temp; 
    
        while (begin < end) 
        { 
            temp = array[begin]; 
            array[begin] = array[end]; 
            array[end] = temp; 
    
            begin++; 
            end--; 
        } 
    } 
    

    其实前段时间还考虑过这个问题,问题是由一个排序的功能引起的。老赵,您见多识广,给我点建议。我那时候想,排序就会涉及正序(ASC)和逆序(DESC)

    • 第1个问题,正序逆序的区别是放在比较的逻辑里,还是,先不管三七二十一,给你正序排好,你要反序,我再把排好的倒一下。
    • 第2个问题,接第1个,如果我采用Reverse的方法,那比较好的Reverse算法是什么?

    当然,这个已经挺好了(O(n)),哈哈.我本来想看看.net framework的Array.Reverse的实现,可惜没看着。

    麻烦您了...

  137. 老赵
    admin
    链接

    老赵 2009-06-05 23:29:00

    @危亭
    一般是应该放在比较逻辑里,不要Reverse,但是肯定有特殊情况。
    例如你需要反序排,但是目前已经是正序的情况下。

  138. 危亭
    *.*.*.*
    链接

    危亭 2009-06-06 22:00:00

    Thanks a lot.

  139. Denuvead
    *.*.*.*
    链接

    Denuvead 2009-06-22 13:32:00

    拜师~

  140. Denuvead
    *.*.*.*
    链接

    Denuvead 2009-06-22 13:50:00

    还有一个朋友认为用栈:把begin到end之间的元素给push到栈中,再一个一个pop出来依次赋值给begin到end,这样就反序了……唔!数据结构学的不错!

    这个难道新建立一个栈? 然后循环从begin 到end的数据 push?
    然后在循环begin 到end的数据赋值 栈的pop?

    不知道我理解的对不对
    不过我怎么觉得这是画蛇添足啊

  141. 老赵
    admin
    链接

    老赵 2009-06-22 14:02:00

    @Denuvead
    文章不也是你这个意思么,呵呵。

  142. eleven1012
    *.*.*.*
    链接

    eleven1012 2009-06-22 19:35:00

    虽然答案和我第一反应想的一样,但感觉自己还是很菜。.net让我们变的越来越蠢了。应该多练习一下这种基础的算法。

  143. 老赵
    admin
    链接

    老赵 2009-06-22 21:19:00

    @eleven1012
    兄弟们真觉得这些是“算法”吗?

  144. kgame[未注册用户]
    *.*.*.*
    链接

    kgame[未注册用户] 2009-06-29 09:25:00

    忽略使用者輸入錯誤的可能,因為下標錯誤時,陣列就會幫我們丟XD

    public static void Reverse(int[] array, int begin, int end) 
    { 
        while (end > begin) 
        { 
            array[begin] ^= array[end]; 
            array[end] ^= array[begin]; 
            array[begin] ^= array[end]; 
    
            begin++; 
            end--; 
        } 
    }
    
  145. 老赵
    admin
    链接

    老赵 2009-06-29 09:59:00

    @kgame
    运行时自己抛出的信息是不友好的

  146. happy_ud
    *.*.*.*
    链接

    happy_ud 2009-06-29 16:45:00

    int x=begin-end+1; 
    while (begin<= x/2) 
    { 
        int temp = array[begin]; 
        array[begin] = array[x-begin]; 
        array[x-begin] = temp; 
        begin++; 
    } 
    
  147. chen8854[未注册用户]
    *.*.*.*
    链接

    chen8854[未注册用户] 2009-06-30 20:30:00

    根据老赵给的答案测试有错

    using System; 
    using System.Collections.Generic; 
    using System.Text; 
    
    namespace TestReverse 
    { 
        class Program 
        { 
            static void Main(string[] args) 
            { 
                int[] array = { 0,1,2,3,4,5,6,7,8,9}; 
                try 
                { 
                    Reverse(array, 4, 9); 
                } 
                catch (Exception err) 
                { 
                    Console.WriteLine(err.ToString()); 
                } 
    
                Console.ReadLine(); 
            } 
    
            static void Reverse(int[] array, int begin, int end) 
            { 
                if (array == null) 
                { 
                    throw new ArgumentNullException("array", "array不能为空"); 
                } 
    
                if (begin < 0) 
                { 
                    throw new ArgumentOutOfRangeException("begin", "begin不能小于0"); 
                } 
    
                if (end < begin) 
                { 
                    throw new ArgumentOutOfRangeException("end不能小于begin", (Exception)null); 
                } 
    
                if (end >= array.Length) 
                { 
                    throw new ArgumentOutOfRangeException("end", "end超过array最大下标"); 
                } 
    
                int temp = array[begin]; 
                array[begin] = array[end]; 
                array[end] = temp; 
    
                begin++; 
                end--; 
    
                Display(array); 
            } 
    
            static void Display(int[] array) 
            { 
                string temp = null; 
                for (int i = 0; i <= array.Length - 1; i++) 
                { 
                    temp = temp+" " + array[i].ToString(); 
                } 
                Console.WriteLine(temp); 
            } 
        } 
    } 
    

    请运行测试下就知道了,结果竟然是:0 1 2 3 9 5 6 7 8 4

  148. 老赵
    admin
    链接

    老赵 2009-06-30 21:15:00

    @chen8854
    这真是我给的答案吗?
    我不用运行就看出你的代码错在什么地方了。

  149. flaky[未注册用户]
    *.*.*.*
    链接

    flaky[未注册用户] 2009-07-13 16:12:00

    mark
    学习了

    http://blog.163.com/flaky_xd/blog/static/300106200961334916607/

  150. 老赵
    admin
    链接

    老赵 2009-07-13 16:39:00

    @flaky
    转载请注明出处。

  151. Dvid[未注册用户]
    *.*.*.*
    链接

    Dvid[未注册用户] 2009-07-17 01:24:00

    public static void reverge(int[] arrar, int begin, int end)
    {
        try
        {
            if (arrar.Length > 0 && arrar.Length > begin && arrar.Length > end)
            {
                for (int i=0; i < (end - begin + 1) / 2; i++)
                {
                    int temp = arrar[begin - i];
                    arrar[begin - i] = arrar[end - i];
                    arrar[end - i] = temp;
                }
            }
        }
        catch (Exception e)
        {
            throw (e);
        }
    }
    

    这个应该行哈?

  152. 老赵
    admin
    链接

    老赵 2009-07-17 08:40:00

    @Dvid
    不行,原因看内容。

  153. tube[未注册用户]
    *.*.*.*
    链接

    tube[未注册用户] 2009-08-10 16:46:00

    我有幸让您面试过,这个题目我写正确了,但是您给我的第二道题目把我kill了。

  154. ——初学者[未注册用户]
    *.*.*.*
    链接

    ——初学者[未注册用户] 2009-08-28 16:42:00

    菜鸟。。写完之后来和各位前辈对比下,受益不少。

    for (int i = end; i >= begin; i--)
    {
        for (int j = begin; j < i; j++)
        {
            if (test[j] > test [j+ 1])
            {
                int temp = test[j];
                test[j] = test[j + 1];
                test[j + 1] = temp;
            }
        }
    }
    
    foreach(int f in ff)
        Console.Write(f+" ");
    
  155. 高歌
    *.*.*.*
    链接

    高歌 2009-09-11 08:57:00

    @chen8854
    while循环没有加

  156. jkj
    202.96.122.*
    链接

    jkj 2010-05-10 20:16:36

    如一个数组初始值是[1, 2, 3, 4, 5, 6],begin为1,end为4,那么当调用了Reverse之后,array数组中的元素便依次成为[1, 5, 4, 3, 2, 6],我不懂为什么会这样!不应该是[4, 3, 2, 1, 5, 6]吗?

  157. 老赵
    admin
    链接

    老赵 2010-05-10 21:29:16

    @jkj

    0-based array

  158. yashi88
    65.49.2.*
    链接

    yashi88 2010-05-13 16:11:00

    public static void Reverse(int[] array, int begin, int end)
    {
        if ( array == null )
            throw new ArgumentNullException();
        if((begin < 0) || (begin >= array.Length) || (begin > end))
            throw new ArgumentException();
    
        if((end < 0) || (end >=array.Length))
            throw new ArgumentException();
    
        int a=0,b=begin, e=end;
        if(b == e)
            return;
    
        while (b < e)
        {
            a = array[b];
            array[b] = array[e];
            array[e] = a;
            b++;
            e--;
        }
    }
    

    }

    看来我的思路和老赵差不多吗。

  159. hi
    122.84.3.*
    链接

    hi 2011-03-04 22:42:51

    public static void Reverse(int[] array, uint begin, uint end)
    {
        try
        {
            if (null == array)
            {
                throw new ArgumentNullException("array", "array不能为null");
            }
            if (end < begin)
            {
                throw new ArgumentException("end", "end必须大于begin...");
            }
            else if (end > array.Length)
            {
                throw new ArgumentException("end", "end不能大于array.length");
            }
            while (end > begin)
            {
                array[begin] ^= array[end];
                array[end] = array[begin] ^ array[end];
                array[begin] ^= array[end];
                begin++;
                end--;
            }
        }
        catch (ArgumentException ex)
        {
            Console.WriteLine(ex.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
    
  160. 老赵
    admin
    链接

    老赵 2011-03-05 09:45:25

    @hi

    为啥要加try...catch呢?

  161. zy
    119.32.67.*
    链接

    zy 2011-05-03 22:14:48

    public static void Reverse(int[] array, int begin, int end)
    {
        if (array == null)
            throw new ArgumentNullException();
        if (begin < 0 || end < 0 || begin <= 0 || end >= array.Length)
            throw new ArgumentOutOfRangeException();
        if (begin >= end)
            throw new ArgumentException();
    
        for (int i = begin; i < (end - begin) / 2; i++)
        {
            int temp = array[i];
            array[i] = array[array.Length - 1 - i];
            array[array.Length - 1 - i] = temp;
        }
    }
    

    大专出来的,学校也和北大青鸟合作过。个人认为这还得靠自己自觉,想学习的从北大青鸟那里也可以学到很多东西。 不过大专出来的在数据结构和数学方面是要欠缺点。

  162. zy
    119.32.67.*
    链接

    zy 2011-05-03 22:15:42

    public static void Reverse(int[] array, int begin, int end) {

    if (array == null)
                throw new ArgumentNullException();
    
            if (begin < 0 || end < 0 || begin <= 0 || end >= array.Length)
                throw new ArgumentOutOfRangeException();
    
            if (begin >= end)
                throw new ArgumentException();
    
            for (int i = begin; i < (end - begin) / 2; i++)
            {
                int temp = array[i];
                array[i] = array[array.Length - 1 - i];
                array[array.Length - 1 - i] = temp;
            }
        }
    

    咋个格式不工整··

  163. 小李2012
    210.13.75.*
    链接

    小李2012 2011-08-05 20:46:03

    /// <summary>
    /// 将array数组中,从begin下标到end下标之间的元素反序一下
    /// </summary>
    /// <param name="array">数组</param>
    /// <param name="begin">起始下标</param>
    /// <param name="end">结束下标</param>
    public static void Reverse(int[] array, int begin, int end)
    {
    
        if(begin<0)
            throw new Exception("begin下标不能小于0");
        int len = array.Length;
        if (len <= end)
            throw new Exception("end下标不能大于数组长度");
    
        if(begin>end)
            throw new Exception("end下标不能小于begin下标");
    
        if (begin == end)
            return;
    
        int size = end - begin+1;
    
        int[] temp = new int[] { };
        Array.Resize<int>(ref temp, size);
        Array.Copy(array, begin, temp, 0, size);
    
        Array.Reverse(temp);
    
        Array.Copy(temp, 0, array, begin, size);
    
    } 
    

    希望指正

  164. 小李2012
    210.13.75.*
    链接

    小李2012 2011-08-05 20:48:08

    不好意思,忘记处理数组为null或者数组为空的情况了

  165. james
    221.181.90.*
    链接

    james 2011-08-05 21:32:04

    最直观的:

    public static void Reverse(int[] array, int begin, int end) {
        // 确保参数正确
        if (array == null || array.isEmpty() || begin >= end || begin < 0 || end > array.length) {
            return;
        }
    
        // 把反序的结果存进一个临时数组
        int tmparr = new int[end - begin + 1];
        for (int i = end; i > begin -1; i++) {
            tmparr[end - i] = array[i];
        }
    
        // 把反序的数据存回原始数组
        for (int i = begin; i < end + 1; i++) {
            array[i] = tmparr[i + begin];
        }
    }
    
  166. james
    221.181.90.*
    链接

    james 2011-08-05 21:32:44

    比较省内存的

    public static void Reverse(int[] array, int begin, int end) {
        if (array == null || array.isEmpty() || begin >= end || begin < 0 || end > array.length) {
            return;
        }
    
        // 头尾对调
        for (int i = 0; i < (end - begin + 1) / 2 + 1; i++) {
            if (begin + i != end - i) {
                int tmp = array[begin + i];
                array[begin + i] = array[end - i];
                array[end - i] = tmp;
            }
        }
    }
    
  167. ddou
    110.217.83.*
    链接

    ddou 2011-08-05 21:34:04

    有意思!学习了!

  168. KylinHuang
    124.160.106.*
    链接

    KylinHuang 2011-08-05 22:30:51

    # Python
    def Reverse(array, begin, end):
        if 0 <= begin < end < len(array):
            j = end
            for i in xrange(begin, end):
                j -= 1
                if i < j:
                    array[i], array[j] = array[j], array[i]
                else:
                    return
        else:
            raise Exception("Wrong Param")
    
  169. Funeral
    221.223.249.*
    链接

    Funeral 2011-08-05 22:33:25

    Python版(3.x):

    def Reverse(array,begin,end):
    
    
    if(type(array) is not type(list)):    #array的类型必须是list
        raise Exception("<array> is not list")
    
    
    if (array is None) or (len(array) == 0):    #array不能为None或者不包含元素
        raise Exception("<array> is None or Empty")
    
    
    if (begin < 0) or (begin >= len(array)):    #begin参数不能小于0或者大于列表(数组)长度
        raise Exception("<begin> less than 0 or more than <array>'s length")
    
    
    if (end < 0) or (end >= len(array)):     #end参数不能小于0或者大于列表(数组)长度
        raise Exception("<end> less than 0 or more than <array>'s length")
    
    
    if (begin > end):     #begin参数不能大于end参数
        raise Exception("<begin> can't less than <end>")
    
    if(begin == end):
        return
    
    while begin < end:
        temp = array[begin]
        array[begin] = array[end]
        array[end] = temp
        begin = begin + 1
        end = end - 1
    

    调用:
    array = [0,1,2,3,4,5,6,7,8,9]
    Reverse(array,1,4)
    print(array)

  170. KylinHuang
    124.160.106.*
    链接

    KylinHuang 2011-08-05 22:44:49

    好吧。。我完全不自觉地会把传入参数拷贝一个副本再去修改副本。。

  171. jjlin_0
    218.205.147.*
    链接

    jjlin_0 2011-08-19 16:12:58

    public static void Reverse(int[] array,int intBeginIndex,int intEndIndex)
    {
        if (array == null) throw new ArgumentNullException("array", "array不能为空!");
    
        if (intBeginIndex < 0) throw new IndexOutOfRangeException("起始参数不能小于0");
    
        if (intEndIndex > array.Length - 1) throw new IndexOutOfRangeException("结束参数不能超过数组的上限!");
    
        if (intBeginIndex > intEndIndex) throw new Exception("起始参数不能大于结束参数");
    
        int intDif;
        intDif = intEndIndex - intBeginIndex;
    
        for (int i=0;i<=intDif/2;i++)
        {
            int intTemp = array[intEndIndex - i];
            array[intEndIndex - i] = array[intBeginIndex + i];
            array[intBeginIndex + i] = intTemp;
        }
    }
    
  172. 好汗啊
    124.74.111.*
    链接

    好汗啊 2011-11-29 12:55:03

    这完全是看这人智商够不够用吧

  173. bigmonster
    182.48.112.*
    链接

    bigmonster 2012-02-16 11:37:55

    偶然看到,做了一下,比较符合LZ的思路

    public static void Reverse(int[] array, int begin, int end)
    {
        // 异常校验
        if(array == null)
            throw new ArgumentNullException("array is null");
        if (begin < 0 || end > array.Length - 1 || begin > end)
            throw new ArgumentException("pls check begin and end");
    
        int temp = 0;
        while (begin < end)
        {
            temp = array[begin];
            array[begin] = array[end];
            array[end] = temp;
    
            begin++;
            end--;
        }
    
    }
    
  174. 链接

    祝威 2014-10-14 17:33:43

    做了一下,居然全对~ throw new ArgumentOutOfRangeException("end不能小于begin", (Exception)null); 这一句受益匪浅~

发表回复

登录 / 登录并记住我 ,登陆后便可删除或修改已发表的评论 (请注意保留评论内容)

昵称:(必填)

邮箱:(必填,仅用于Gavatar

主页:(可选)

评论内容(大于5个字符):

  1. Your Name yyyy-MM-dd HH:mm:ss

使用Live Messenger联系我