代码优化如做游戏一样有趣

认认真真地写好一段代码,写好一个函数,也是很有乐趣的一件事情。


1. 比如说对于这样一个小题目:

在一50人的队列中,从左至右报数,为单数者出列,其他人再从左至右报数,为单数者出列,直至剩下最后一人,问此人是初始队列中的第多少号?

意看到这个描述,那么当然有一种顺理成章的做法,如下所示:

namespace Exam01
{
    using System.Collections.Generic;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class Utility
    {
        private List<int> numbers = new List<int>();

        public Utility()
        {
            for (int i = 1; i <= 50; i++)
            {
                numbers.Add(i);
            }
        }

        public int Run()
        {
            while (numbers.Count > 1)
            {
                int start =
                    ((numbers.Count >> 1) << 1) == numbers.Count ?
                    numbers.Count - 1 :
                    numbers.Count;

                for (int i = start - 1; i >= 0; i -= 2)
                {
                    numbers.RemoveAt(i);
                }
            }

            return numbers[0];
        }
    }
}

这个做法显然不是最优的。

经过简单的分析,我们可以看到,每一轮去除单数元素后,每次得到的新的数列中,第一个元素的值是很有规律的。这个规律就是2的n次方,n从0开始取值。

所以上面的Run()函数我们优化为下面这样的:

        public int Run()
        {
            int start = 1;
            int k = 50 >> 1;
            while (start <= k)
            {
                start <<= 1;
            }

            return start;
        }

再举两个代码优化的小例子:

2. 如何把月份转换成季度

先看一下某论坛帖子里面的代码:

public int ConvertMonthToQuarter(int month)
{ 
    double f = Convert.ToDouble(month)/3f;
    if (f > Convert.ToInt32(f))
    {
        return Convert.ToInt32(f) + 1;
    }

    return Convert.ToInt32(f);
}

这段代码当然质量是惨不忍睹的。下面是我的优化:

/// <summary>
/// Get quarter of the year by month value.
/// Notice: valid month range is [1 -- 12]
/// </summary>
/// <param name="month">month value.</param>
/// <returns>quarter value of the year</returns>
public int GetQuarterByMonth(int month)
{
    if (month < 1 || month > 12)
    {
        string message = string.Format("Input parameter month ({0}) out of range[1 -- 12].", month);
        throw new ArgumentOutOfRangeException("month", message);
    }

    int q = month / 3;
    return q * 3 < month ? q + 1 : q;
}

然后,略微一思考,进一步优化如下:

/// <summary>
/// Get quarter of the year by month value.
/// Notice: valid month range is [1 -- 12]
/// </summary>
/// <param name="month">month value.</param>
/// <returns>quarter value of the year</returns>
public int GetQuarterByMonth(int month)
{
    if (month < 1 || month > 12)
    {
        string message = string.Format("Input parameter month ({0}) out of range[1 -- 12].", month);
        throw new ArgumentOutOfRangeException("month", message);
    }

    return (month - 1) / 3 + 1;
}

现在这个函数看起来终于像样了吧。


3. 获得本月份是本季度的第几个月

先看一下某论坛帖子里面的代码:

public int GetMonthOfQuarter(int month)
{
    int num = month % 3;
    if (num == 0)
    {
        return 3;
    }

    return num;
}

我对其优化如下:

/// <summary>
/// Get month sequence of the quarter.
/// Notice: valid month range is [1 -- 12]
/// </summary>
/// <param name="month">month value.</param>
/// <returns>month sequence of the quarter</returns>
public int GetMonthSeqOfQuarter(int month)
{
    if (month < 1 || month > 12)
    {
        string message = string.Format("Input parameter month ({0}) out of range[1 -- 12].", month);
        throw new ArgumentOutOfRangeException("month", message);
    }

    int k = (month - 1) / 3;
    return month - 3 * k;
}


雕虫小技耳。但是也挺有意思。微笑

你可能感兴趣的:(游戏,优化,String,Class,input,Numbers)