一道面试题引发的有关随机数的思考(6)

来源:互联网 发布:淘宝睡衣店铺名字 编辑:程序博客网 时间:2024/06/07 00:57

在上一篇文章(http://blog.csdn.net/xzjxylophone/article/details/6853624)中,关于效率的问题进行简单的讨论,

现在我就用C#中委托来实现RandN_2,算法都是一样的。

类RandN_2:

//支持2-49,包括2和49public class RandN_2 : Rand7Base{//声明委托,返回true表示已经计算完毕protected delegate bool GetNextResult(int remain, int ceiling, ref int result);private GetNextResult _getNextResult;protected int _remain;       //剩余protected int _ceiling;      //大于的最小数private RandN_2(int maxNum){UpdateMaxNum(maxNum);}public void UpdateMaxNum(int maxNum){_maxNum = maxNum;_remain = _maxNum % 7;decimal chushu = (decimal)_maxNum / 7;_ceiling = (int)Math.Ceiling(chushu);switch (_ceiling){case 1:_getNextResult = NextResult1;break;case 2:_getNextResult = NextResult2;break;case 3:_getNextResult = NextResult3;break;default:_getNextResult = NextResult4567;break;}}//小于等于7的时候protected bool NextResult1(int remain, int ceiling, ref int result){if (remain > _remain){result = Next();return true;}result = remain;return true;}//8-14的时候protected bool NextResult2(int remain, int ceiling, ref int result){if (ceiling == 1){return false;}if (ceiling > 4){result = remain;}else{if (remain > _remain){result = Next();}else{result = remain + 7;}}return true;}//15-21的时候protected bool NextResult3(int remain, int ceiling, ref int result){if (ceiling == 1){return false;}//6,7if (ceiling > 5){result = remain;}else if (ceiling > 3)//4,5{result = remain + 7;}else //2,3{if (remain > _remain){result = Next();}else{result = remain + 7 * 2;}}return true;}//22-49的时候protected bool NextResult4567(int remain, int ceiling, ref int result){if (ceiling > _ceiling)return false;result = remain + (ceiling - 1) * 7;if (ceiling == _ceiling && _remain != 0){if (remain > _remain){result = Next();}}return true;}public static RandN_2 GetInstance(int maxNum){if (rand == null || !(rand is RandN_2)){rand = new RandN_2(maxNum);}else if (rand is RandN_2 && rand.MaxNum != maxNum){((RandN_2)rand).UpdateMaxNum(maxNum);}return (RandN_2)rand;}override public int Next(){int result = 0;int remain = _rand7.Next();bool loop = false;int ceiling = 0;while (!loop){ceiling = _rand7.Next();loop = _getNextResult(remain, ceiling, ref result);}return result;}}


添加测试代码:

static void TestRandN_2(){RandN_2 rand = RandN_2.GetInstance(34);TestRand(rand);rand = RandN_2.GetInstance(35);TestRand(rand);rand = RandN_2.GetInstance(6);TestRand(rand);}

测试结果如下:

计算Rand34的概率如下产生1的概率是:0.0293664产生2的概率是:0.0293180产生3的概率是:0.0293527产生4的概率是:0.0293710产生5的概率是:0.0295124产生6的概率是:0.0293318产生7的概率是:0.0293360产生8的概率是:0.0293739产生9的概率是:0.0294344产生10的概率是:0.0293604产生11的概率是:0.0294201产生12的概率是:0.0293619产生13的概率是:0.0293823产生14的概率是:0.0295176产生15的概率是:0.0293114产生16的概率是:0.0294928产生17的概率是:0.0294471产生18的概率是:0.0293353产生19的概率是:0.0293968产生20的概率是:0.0294575产生21的概率是:0.0294152产生22的概率是:0.0294324产生23的概率是:0.0294275产生24的概率是:0.0294937产生25的概率是:0.0293569产生26的概率是:0.0294170产生27的概率是:0.0294112产生28的概率是:0.0294705产生29的概率是:0.0294017产生30的概率是:0.0293598产生31的概率是:0.0294615产生32的概率是:0.0294824产生33的概率是:0.0295156产生34的概率是:0.0294748耗时: 3.17424430414457 秒Average:0.0294118;Max:0.0295176;Min:0.0293114Max:0.0295176, Max-Average:0.0001058, Bits:0.3598400%Min:0.0293114, Min-Average:-0.0001004, Bits:-0.3412400%计算Rand35的概率如下产生1的概率是:0.0285922产生2的概率是:0.0285493产生3的概率是:0.0285821产生4的概率是:0.0285874产生5的概率是:0.0285950产生6的概率是:0.0286506产生7的概率是:0.0284996产生8的概率是:0.0285676产生9的概率是:0.0285698产生10的概率是:0.0285851产生11的概率是:0.0285485产生12的概率是:0.0286162产生13的概率是:0.0286179产生14的概率是:0.0285686产生15的概率是:0.0286348产生16的概率是:0.0286025产生17的概率是:0.0285430产生18的概率是:0.0285673产生19的概率是:0.0284558产生20的概率是:0.0286432产生21的概率是:0.0285322产生22的概率是:0.0285425产生23的概率是:0.0285563产生24的概率是:0.0286283产生25的概率是:0.0285434产生26的概率是:0.0285640产生27的概率是:0.0285837产生28的概率是:0.0285114产生29的概率是:0.0285032产生30的概率是:0.0284974产生31的概率是:0.0285877产生32的概率是:0.0286038产生33的概率是:0.0286174产生34的概率是:0.0285587产生35的概率是:0.0285935耗时: 3.20557551823726 秒Average:0.0285714;Max:0.0286506;Min:0.0284558Max:0.0286506, Max-Average:0.0000792, Bits:0.2771000%Min:0.0284558, Min-Average:-0.0001156, Bits:-0.4047000%计算Rand6的概率如下产生1的概率是:0.1670055产生2的概率是:0.1666923产生3的概率是:0.1664376产生4的概率是:0.1666388产生5的概率是:0.1665858产生6的概率是:0.1666400耗时: 2.94888697894323 秒Average:0.1666667;Max:0.1670055;Min:0.1664376Max:0.1670055, Max-Average:0.0003388, Bits:0.2033000%Min:0.1664376, Min-Average:-0.0002291, Bits:-0.1374400%

可以看出在计算Rand6的时候,速度快了很多。

现在既然已经解决了49以内的随机数,那么有没有可能用Rand7计算任意的一个随机数了?

答案是肯定的,下一篇文章我们来解决如何去解决任意一个数


原创粉丝点击