亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C#實現(xiàn)搶紅包算法的示例代碼

 更新時間:2022年03月10日 08:27:48   作者:猿來到此  
很多商家都會使用紅包進行促銷,那么你知道紅包算法是怎么實現(xiàn)的嗎,本文主要介紹了C#實現(xiàn)搶紅包算法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

二倍均值法(公平版) 

發(fā)出一個固定金額的紅包,由若干個人來搶,需要滿足哪些規(guī)則?

1.所有人搶到金額之和等于紅包金額,不能超過,也不能少于。

2.每個人至少搶到一分錢。

3.要保證所有人搶到金額的幾率相等。

假設剩余紅包金額為M,剩余人數(shù)為N,那么有如下公式:

每次搶到的金額 = 隨機區(qū)間 (0, M / N × 2)

這個公式,保證了每次隨機金額的平均值是相等的,不會因為搶紅包的先后順序而造成不公平。舉個例子:

假設有10個人,紅包總額100元。100/10×2 = 20, 所以第一個人的隨機范圍是(0,20 ),平均可以搶到10元。
假設第一個人隨機到10元,那么剩余金額是100-10 = 90 元。90/9×2 = 20, 所以第二個人的隨機范圍同樣是(0,20 ),平均可以搶到10元。
假設第二個人隨機到10元,那么剩余金額是90-10 = 80 元。80/8×2 = 20, 所以第三個人的隨機范圍同樣是(0,20 ),平均可以搶到10元。
以此類推,每一次隨機范圍的均值是相等的。

  static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                var list = DivideRedPackage(100* 100, 10);
                Console.WriteLine(string.Join(",", list));
                int count = 0;
                foreach (var item in list)
                {
                    count += item;
                }
                Console.WriteLine(count);
            }
            System.Console.ReadKey();
        }
 
        /// <summary>
        /// 產(chǎn)生紅包數(shù)組
        /// </summary>
        /// <param name="cashCount">紅包總金額,單位分</param>
        /// <param name="peopleNumber">紅包人數(shù)</param>
        /// <returns></returns>
        static List<int> DivideRedPackage(int cashCount, int peopleNumber)
        {
            List<int> redPackageList = new List<int>();
            if (cashCount <= peopleNumber)
            {
                for (int i = 0; i < cashCount; i++)
                {
                    redPackageList.Add(1);
                }
 
                return redPackageList;
            }
 
            Random random   = new Random(GetRandomSeed());
            int    restCash = cashCount, restPeople = peopleNumber;
            for (int i = 0; i < peopleNumber - 1; i++)
            {
                var cash = random.Next(1, restCash / restPeople * 2);
                restCash -= cash;
                restPeople--;
                redPackageList.Add(cash);
            }
            redPackageList.Add(restCash);
            return redPackageList;
        }

例如,產(chǎn)生的結果如下:

1960,189,234,1763,1211,1236,1340,53,1652,362
10000
1032,1380,456,1885,608,857,1541,452,1273,516
10000
976,955,749,936,1990,1177,781,325,527,1584
10000
794,935,272,216,2034,522,455,2313,2260,199
10000
1376,1539,1292,614,443,1874,889,544,821,608
10000
914,15,877,1738,604,932,321,983,3106,510
10000
659,791,800,1066,788,908,991,2473,495,1029
10000
1256,733,1385,667,1192,1237,455,105,2121,849
10000
1941,1173,567,1280,1558,618,183,644,133,1903
10000
1313,735,1198,1173,1288,522,1879,1155,59,678
10000

上述示例中需注意,Random是一個偽隨機數(shù)生成器,在大多數(shù) Windows 系統(tǒng)上,Random 類 (System) | Microsoft Docs 15 毫秒內(nèi)創(chuàng)建的對象可能具有相同的種子值。因此,如果New Random在循環(huán)中使用,就必須提供隨機的種子值。我們可以使用RNGCryptoServiceProvider 類 (System.Security.Cryptography) | Microsoft Docs類產(chǎn)生隨機樹種子。具體代碼如下:

        /// <summary>
        /// 產(chǎn)生加密的隨機數(shù)種子值
        /// </summary>
        /// <returns></returns>
        static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider rng =
                new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }

線段切割法(手速版) 

算法思路如下:

線段分割法就是把紅包總金額想象成一條線段,而每個人搶到的金額,則是這條主線段所拆分出的子線段。

當N個人一起搶紅包的時候,就需要確定N-1個切割點。

因此,當N個人一起搶總金額為M的紅包時,我們需要做N-1次隨機運算,以此確定N-1個切割點。

隨機的范圍區(qū)間是(1, M)。當所有切割點確定以后,子線段的長度也隨之確定。這樣每個人來搶紅包的時候,只需要順次領取與子線段長度等價的紅包金額即可。

需要注意一下兩點:

1.每個人至少搶到一分錢。

2.分割的線段如果重復需要重新切割

具體代碼如下:

    class Program
    {
        static List<int> DivideRedPackage(int cashCount, int peopleNumber)
        {
            List<int> redPackageList = new List<int>();
            if (cashCount <= peopleNumber)
            {
                for (int i = 0; i < cashCount; i++)
                {
                    redPackageList.Add(1);
                }
                return redPackageList;
            }
 
            Random    random     = new Random(GetRandomSeed());
            int       restPeople = peopleNumber;
            List<int> lineList   = new List<int>();
            while (restPeople > 1)
            {
                var line = random.Next(1, cashCount);
                if (lineList.Contains(line) == false)
                {
                    lineList.Add(line);
                    restPeople--;
                }
            }
            lineList.Sort();
 
            redPackageList.Add(lineList[0]);
            for (int i = 0; i < peopleNumber - 2; i++)
            {
                var cash = lineList[i + 1] - lineList[i];
                redPackageList.Add(cash);
            }
            redPackageList.Add(cashCount - lineList[lineList.Count - 1]);
            return redPackageList;
        }
        static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            System.Security.Cryptography.RNGCryptoServiceProvider rng =
                new System.Security.Cryptography.RNGCryptoServiceProvider();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }
        static void Main(string[] args)
        {
            for (int i = 0; i < 10; i++)
            {
                var list = DivideRedPackage(100 * 100, 10);
                Console.WriteLine(string.Join(",", list));
                int count = 0;
                foreach (var item in list)
                {
                    count += item;
                }
                Console.WriteLine(count);
            }
            System.Console.ReadKey();
        }
    }

輸出結果如下:

409,2233,1843,546,983,679,1621,460,369,857
10000
50,472,281,603,577,1007,3929,38,591,2452
10000
194,1241,675,209,3507,1714,1199,596,313,352
10000
2127,578,16,2413,1332,586,91,260,465,2132
10000
1015,1421,963,626,3031,955,171,1112,60,646
10000
118,352,1062,1128,8,374,1879,1707,1755,1617
10000
2805,592,391,90,1468,392,2201,40,1426,595
10000
145,251,2910,59,1065,235,2761,997,1564,13
10000
814,1725,1886,39,696,202,44,992,3099,503
10000
828,1281,2402,579,380,2246,154,855,564,711
10000

 到此這篇關于C#實現(xiàn)搶紅包算法的示例代碼的文章就介紹到這了,更多相關C# 搶紅包算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • C#實現(xiàn)無損壓縮圖片的示例詳解

    C#實現(xiàn)無損壓縮圖片的示例詳解

    這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)無損壓縮圖片功能,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以了解一下
    2022-12-12
  • C#匿名委托和Java匿名局部內(nèi)部類使用方法示例

    C#匿名委托和Java匿名局部內(nèi)部類使用方法示例

    Java在嵌套類型這里提供的特性比較多,假設:Java的字節(jié)碼只支持靜態(tài)嵌套類,內(nèi)部類、局部內(nèi)部類和匿名局部內(nèi)部類都是編譯器提供的語法糖,這個假設目前沒法驗證(看不懂字節(jié)碼),本文先來看一下C#是如何為我們提供的這種語法糖
    2013-11-11
  • c#下注冊表操作的一個小細節(jié)

    c#下注冊表操作的一個小細節(jié)

    c#下注冊表操作的一個小細節(jié)...
    2007-11-11
  • 詳解ASP.NET中Identity的身份驗證代碼

    詳解ASP.NET中Identity的身份驗證代碼

    這篇文章主要介紹了ASP.NET Identity 的“多重”身份驗證代碼,以及實現(xiàn)的原理講解,需要的朋友參考一下。
    2017-12-12
  • C#中定時任務被阻塞問題的解決方法

    C#中定時任務被阻塞問題的解決方法

    這篇文章主要給大家介紹了關于C#中定時任務被阻塞問題的解決方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用c#具有一定的參考學習價值,需要的朋友可以參考下
    2021-11-11
  • C#利用GDI+給圖片添加文字(文字自適應矩形區(qū)域)

    C#利用GDI+給圖片添加文字(文字自適應矩形區(qū)域)

    這篇文章主要給大家介紹了關于C#利用GDI+給圖片添加文字(文字自適應矩形區(qū)域)的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起看看吧。
    2018-04-04
  • C# 使用Free Spire.Presentation 實現(xiàn)對PPT插入、編輯、刪除表格

    C# 使用Free Spire.Presentation 實現(xiàn)對PPT插入、編輯、刪除表格

    小編發(fā)現(xiàn)使用.NET組件——Free Spire.Presentation,在C#中添加該產(chǎn)品DLL文件,可以簡單快速地實現(xiàn)對演示文稿的表格插入、編輯和刪除等操作,具體實現(xiàn)代碼大家參考下本文吧
    2017-09-09
  • 一文掌握C# ListView控件的用法和示例代碼

    一文掌握C# ListView控件的用法和示例代碼

    ListView控件提供了豐富的屬性和事件,可以用于實現(xiàn)各種各樣的表格視圖,包括帶有單元格編輯、排序和分組等功能,本文介紹了一些常見的?ListView?控件的用法和示例代碼,感興趣的朋友一起看看吧
    2024-02-02
  • C#實現(xiàn)剪切板功能

    C#實現(xiàn)剪切板功能

    這篇文章主要為大家詳細介紹了C#實現(xiàn)剪切板功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 淺談C#中Md5和Sha1兩種加密方式

    淺談C#中Md5和Sha1兩種加密方式

    這篇文章主要介紹了淺談C#中Md5和Sha1兩種加密方式的相關資料,需要的朋友可以參考下
    2015-07-07

最新評論