在上一篇文章(http://blog.csdn.net/xzjxylophone/article/details/6853624)中,关于效率的问题进行简单的讨论,
现在我就用C#中委托来实现RandN_2,算法都是一样的。
类RandN_2:
//支持2-49,包括2和49 public 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,7 if (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.0293114 Max: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.0284558 Max: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.1664376 Max:0.1670055, Max-Average:0.0003388, Bits:0.2033000% Min:0.1664376, Min-Average:-0.0002291, Bits:-0.1374400%
现在既然已经解决了49以内的随机数,那么有没有可能用Rand7计算任意的一个随机数了?
答案是肯定的,下一篇文章我们来解决如何去解决任意一个数