Random Number Generated by Lower Sign

Keywords: Java less

At present, in many similar transactions in the stock market, many project issuance needs to be subscribed for, until the end of the subscription, the number of subscribers is determined by the subscription number.

If user U1 purchases 10 products, then the end number of the product he purchases is 10000001 to 100000010, and user U2 purchases five more, then U2's end number is 100000011 to 10000015.

Now if we issue item A, the circulation is 12345 and the subscription is 675893. Signature number in random generation:

  1. package com.fbd.core.util;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.Iterator;  
  5. import java.util.LinkedHashMap;  
  6. import java.util.List;  
  7. import java.util.Map;  
  8. import java.util.Map.Entry;  
  9.   
  10. import com.fbd.core.exception.ApplicationException;  
  11.   
  12. /** 
  13.  * Logo-in Tool Class Generates Logo-in Number 
  14.  *  
  15.  * @author Lip 
  16.  * 
  17.  */  
  18. public class LotterySystem {  
  19.     //Number of tails selected  
  20.     // public static long chooseNum = 0;  
  21.   
  22.     public static void main(String[] args) {  
  23.         //Initial Purchase Sequence Number  
  24.         long start = 10000000001L;  
  25.         //Actual purchase quantity  
  26.         long purchaseNum =675893;  
  27.         //Actual issuance  
  28.         long distributeNum = 12345;  
  29.         Map<String, Integer> distributeMap = getLottery(purchaseNum, distributeNum);  
  30.         int total = 0;  
  31.         Iterator iterator = distributeMap.entrySet().iterator();  
  32.         while (iterator.hasNext()) {  
  33.             Entry entry = (Entry) iterator.next();  
  34.             System.out.println(entry.getKey() + ":" + entry.getValue());  
  35.             total += (int) entry.getValue();  
  36.         }  
  37.         System.out.println("Number of successful signatures:" + total);  
  38.     }  
  39.   
  40.     /** 
  41.      * Get the number of winning signatures for each mantissa 
  42.      *  
  43.      * @param purchaseNum 
  44.      * @param distributeNum 
  45.      * @return 
  46.      */  
  47.     public static Map<String, Integer> getLottery(long purchaseNum, long distributeNum) {  
  48.         //Number and quantity of signatures  
  49.         Map<String, Integer> distributeMap = new LinkedHashMap<>();  
  50.         if (purchaseNum <= distributeNum) {  
  51.             int n1 = (int) (purchaseNum % 10);  
  52.             int n2 = (int) (purchaseNum / 10);  
  53.             for (int i = 0; i < 10; i++) {  
  54.                 if (i >= n1)  
  55.                     distributeMap.put(i + "", n2);  
  56.                 else  
  57.                     distributeMap.put(i + "", n2 + 1);  
  58.             }  
  59.             return distributeMap;  
  60.         }  
  61.         long chooseNum = 0;  
  62.         double allocationRate = distributeNum * 1.0 / purchaseNum;// 0.001204177...  
  63.         System.out.println("Lottery rate:" + allocationRate);  
  64.         int len = getDigitNum(purchaseNum);  
  65.         long distributeX = (long) (allocationRate * Math.pow(10, len));// 1204177  
  66.         List<Integer> digitList = getEachDigit(distributeX, len);// 1,2,0,4,1,7,7  
  67.         int lenX = getDigitNum(distributeX);  
  68.         List<Long> distributeList = new ArrayList<>();  
  69.         for (int i = 0; i < digitList.size(); i++) {  
  70.             int rate = digitList.get(i);  
  71.             //The remainder of the tail number, such as 232,158, may also win the prize.  
  72.             long temp = (long) (purchaseNum % Math.pow(10, len - lenX + 1 + i));  
  73.             for (int j = 0; j < rate; j++) {  
  74.                 if (chooseNum == distributeNum)  
  75.                     return distributeMap;  
  76.                 //How many random numbers are there?  
  77.                 String lotteryNum = getRandom(distributeList, len - lenX + 1 + i);  
  78.                 int number = (int) (purchaseNum * Math.pow(10, -(len - lenX + 1 + i)));  
  79.                 long lotteryLong = Long.parseLong(lotteryNum);  
  80.                 if (lotteryLong <= temp && lotteryLong > 0) {  
  81.                     number++;  
  82.                 }  
  83.                 if (chooseNum + number <= distributeNum)  
  84.                     chooseNum += number;  
  85.                 else  
  86.                     break;  
  87.                 distributeList.add(lotteryLong);  
  88.                 distributeMap.put(lotteryNum, number);  
  89.             }  
  90.         }  
  91.         int left = (int) (distributeNum - chooseNum);  
  92.         while (left > 0)//Generate a number at a time  
  93.         {  
  94.             String lotteryNum = getRandom(distributeList, len);  
  95.             long lotteryLong = Long.parseLong(lotteryNum);  
  96.             if (lotteryLong > purchaseNum || lotteryLong == 0) {  
  97.                 continue;  
  98.             }  
  99.             distributeList.add(lotteryLong);  
  100.             distributeMap.put(lotteryNum, 1);  
  101.             left--;  
  102.         }  
  103.         return distributeMap;  
  104.     }  
  105.   
  106.     /** 
  107.      * Get the number of digits of a number 
  108.      *  
  109.      * @param value 
  110.      * @return 
  111.      */  
  112.     public static int getDigitNum(long value) {  
  113.         return String.valueOf(value).length();  
  114.     }  
  115.   
  116.     /** 
  117.      * Get a random number of num bits 
  118.      *  
  119.      * @param except 
  120.      * @param num 
  121.      * @return 
  122.      */  
  123.     public static String getRandom(List<Long> except, int num) {  
  124.         boolean confict = true;  
  125.         long obj = 0l;  
  126.         while (confict) {  
  127.             obj = (long) (Math.random() * Math.pow(10, num));  
  128.             while (except.contains(obj) || obj == 0) {//obj is definitely not in except  
  129.                 obj = (long) (Math.random() * Math.pow(10, num));  
  130.             }  
  131.             confict = false;  
  132.             int len = getLen(obj);  
  133.             for (long temp : except) {  
  134.                 int len2 = getLen(temp);  
  135.                 if (len2 == len) {  
  136.                     continue;  
  137.                 }  
  138.                 if (Math.abs(obj - temp) % Math.pow(10, len2) == 0//Conflict  
  139.                 {  
  140.                     confict = true;  
  141.                     break;  
  142.                 }  
  143.             }  
  144.         }  
  145.         return String.format("%0" + num + "d", obj);  
  146.     }  
  147.   
  148.     /** 
  149.      * Get the number of digits of an integer 
  150.      *  
  151.      * @param num 
  152.      * @return 
  153.      */  
  154.     public static int getLen(long num) {  
  155.         int len = 0;  
  156.         while (num != 0) {  
  157.             num /= 10;  
  158.             len++;  
  159.         }  
  160.         return len;  
  161.     }  
  162.   
  163.     /** 
  164.      * Get the winning rate per person 
  165.      *  
  166.      * @param value 
  167.      * @param len 
  168.      * @return 
  169.      */  
  170.     public static List<Integer> getEachDigit(long value, int len) {  
  171.         String valueS = String.valueOf(value);  
  172.         List<Integer> result = new ArrayList<>();  
  173.         for (int i = 0; i < valueS.length() - 1; i++) {  
  174.             result.add(Integer.parseInt(valueS.charAt(i) + ""));  
  175.         }  
  176.         return result;  
  177.     }  
  178.   
  179. }  
The generated signature number is completely random, as follows:

There is a special case need to be noted, that is, the total amount of purchase is very small, less than the circulation, then the equivalent of each tail number is signed, of course, in practice, this situation can not exist, then it means that the project failed. However, this paper solves the special case that the subscription volume is less than or equal to the issuance volume.

The success rate of this project is very low, users U1 and U2 will not be successful.

algorithm Principle:

  1. In the calculation, the signature rate R=12345/675893=0.018264.
  2. Divide decimal digits into decimal digits, the percentile is 1, which means that there is one middle signature number in two digits and 8 in thousand digits, which means that there are eight middle signature numbers in three digits.... Analogy in turn until enough middle signature numbers are generated.
At the end of the shake, you know all the winning numbers and the number of purchases per user, so you can calculate the number of winning signs per user. I use stored procedures to calculate the number of user winners:
  1. BEGIN  
  2.     DECLARE v_num varchar(11);  
  3.   DECLARE v_len int;  
  4.   DECLARE done INT;  
  5.   DECLARE v_result int;  
  6.     DECLARE v_start_result int;  
  7.     DECLARE v_end_result int;  
  8.     DECLARE v_num_pow int;  
  9.   DECLARE cur_success CURSOR FOR SELECT number from lottery_number where project_id=projectId;  
  10.   DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;  
  11.   set v_result = 0;  
  12.     set v_start_result=0;  
  13.     set v_end_result=0;  
  14.   OPEN cur_success;  
  15.   BEGIN_success: LOOP  
  16.      FETCH cur_success INTO v_num;  
  17.      IF done THEN  
  18.          LEAVE BEGIN_success;  
  19.      ELSE  
  20.          set v_len = LENGTH(v_num);  
  21.                  set v_num_pow=POWER(10,v_len);  
  22.          set v_start_result=v_start_result+FLOOR(startNum/v_num_pow);  
  23.                  IF startNum % v_num_pow>v_num THEN   
  24.                          set v_start_result=v_start_result + 1;  
  25.                  END IF;  
  26.          set v_end_result=v_end_result+FLOOR(endNum/v_num_pow);  
  27.                   IF endNum%v_num_pow>=v_num THEN   
  28.                          set v_end_result=v_end_result+1;  
  29.                   END IF;  
  30.      END IF;  
  31.   END LOOP BEGIN_success;  
  32.   CLOSE cur_success;  
  33.     SET v_result=v_end_result-v_start_result;  
  34.     RETURN v_result;  
  35. END  
The principle is very simple. Every user has a start number and an end number. Then only need to calculate the number of winners between 0 and the start number n1, and then calculate the number of winners between 0 and the end number n2. Then n2-n1+1 is the number of winners.

Posted by Earnan on Sun, 09 Jun 2019 17:29:32 -0700