怎样以最快的速度生成10000万个随机的不同16位数?

无·法 2013-08-15 06:45:32
加精
我的方法是借助于数据库的。数据库表的字段设置主键后插入重复数据会提示失败,我就写了个程序不断地往数据库里插入数据,遇到主键重复错误就忽略。代码如下:
Private Sub Command1_Click()
Dim s$
Dim i As Single, sng1 As Single
Dim j%
On Error resume next'当数据库主键字段v_no有重复的时忽略错误
For i = 1 To 10000000
s = ""
For j = 1 To 16'生成随机16位数
Randomize
s = s & Mid("0123456789", Int(Rnd * 9) + 1, 1)
Next
Me.Caption = i & " " & s: DoEvents
conn.Execute "INSERT INTO verify(v_no) VALUES('" & s & "')"
Next
End Sub


我用上述方法生成发现最多也就生成100万个不同的数据。循环一千万次。 当重复执行后,也就是再循环1000万次,数据也就多了一两万而已。 重复的太多!! 怎样最快速的生成呢?? 现在来看这个方法不可行,半个小时了才多几百个新的随机16位数据。
...全文
12396 184 打赏 收藏 转发到动态 举报
写回复
用AI写文章
184 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2014-10-09
  • 打赏
  • 举报
回复
仅供参考
//随机产生100000000个取值范围为[0~2的32次方减1]的数据,
//然后让用户输入一个数据,判断用户输入的数据是不是包含在前面随机产生的数据中。
//要求:当用户输入完成后,必须在1毫秒(千分之一秒)之内完成判断。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <malloc.h>
long int i;
unsigned long ul;
unsigned long *d;
unsigned long ulrand(void) {
    return (
     (((unsigned long)rand()<<24)&0xFF000000ul)
    |(((unsigned long)rand()<<12)&0x00FFF000ul)
    |(((unsigned long)rand()    )&0x00000FFFul));
}
void main() {
    d=(unsigned long *)calloc(1<<(32-5),sizeof(unsigned long));
    if (NULL==d) {
        printf("Can not calloc(%d,%d)!\n",1<<(32-5),sizeof(unsigned long));
        return;
    }
    srand(time(NULL));
    for (i=0;i<100000000;i++) {
        while (1) {
            ul=ulrand();
            if (0==(d[ul>>5]&(1lu<<(ul%32)))) {
                d[ul>>5]|=1<<(ul%32);
                break;
            }
        }
        if (0==i%1000000) printf("%09d,%10lu\n",i,ul);
    }
    while (1) {
        printf("\nInput a number:");
        fflush(stdout);
        rewind(stdin);
        if (1==scanf("%lu",&ul)) break;
    }
    if (d[ul>>5]&(1<<(ul%32))) printf("Include.\n"    );
    else                       printf("Not include.\n");
    free(d);
}
//000000000,2135468533
//001000000,2465805973
//002000000,3844079964
//003000000,1883232874
//004000000,1204697784
//005000000,4050838287
//006000000,3802081245
//007000000,1586042671
//008000000,3119931368
//009000000, 251096899
//010000000,3491239701
//011000000,3365323844
//012000000,2191846708
//013000000,1879478195
//014000000,1112631457
//015000000,1927301519
//016000000,1717332861
//017000000,2922278240
//018000000, 694854106
//019000000, 273255526
//020000000, 398518467
//021000000,3270756812
//022000000,1500289424
//023000000,1502241936
//024000000,1770380660
//025000000,3668842116
//026000000,3255869879
//027000000,1299184024
//028000000,1072990028
//029000000, 242094712
//030000000,3789344297
//031000000,2599365925
//032000000, 962754138
//033000000,2055075654
//034000000,4083452879
//035000000, 489250842
//036000000, 611455230
//037000000, 277350616
//038000000,1597410795
//039000000,3224173662
//040000000,2291446877
//041000000,2546280575
//042000000,2509145642
//043000000,2371773252
//044000000, 635555963
//045000000,2674538666
//046000000,4253690312
//047000000,2675755514
//048000000,1269320296
//049000000,3172516920
//050000000,1430265210
//051000000, 196156173
//052000000,2470825669
//053000000,2536750977
//054000000,1182829949
//055000000,3202826434
//056000000,2263336265
//057000000, 313302924
//058000000,3630264578
//059000000,1154892716
//060000000,2985304230
//061000000,1252204837
//062000000,1292076720
//063000000, 242249250
//064000000,3999999961
//065000000, 431166416
//066000000,1366947236
//067000000,1414387330
//068000000,2143784481
//069000000,3242175409
//070000000,4158065163
//071000000,1425449573
//072000000,2493600232
//073000000,1316783455
//074000000,3723170478
//075000000,3064111466
//076000000, 408557403
//077000000,3722586955
//078000000,3801652651
//079000000,3788160154
//080000000,3329440047
//081000000,1408976868
//082000000, 471838899
//083000000,2145198260
//084000000,3781081738
//085000000,3439027738
//086000000,1150808750
//087000000,2782578638
//088000000,  85604584
//089000000,2704078162
//090000000, 584840269
//091000000,3854577719
//092000000,2823653537
//093000000, 797877025
//094000000,2248017755
//095000000,1787038685
//096000000,2816548567
//097000000, 489107494
//098000000, 911680090
//099000000,3677777147
//
//Input a number:3677777147
//Include.
raindii 2014-10-09
  • 打赏
  • 举报
回复
难点应该在判断是否有重复的数串,按照楼主的方法生成的随机16位数,可以试着自己建立个检索索引,查找出当前串中0有多少个,1有多少个,2有多少个..9有多少个,.然后到索引数组中去检查这个数组是否有重复,大大减少判断时间
熊孩子开学喽 2014-10-08
  • 打赏
  • 举报
回复
引用 181 楼 quanxusheng 的回复:
[quote=引用 180 楼 WallesCai 的回复:] 直接从一个16位数的顺序数组中随机位置抽取数据, 每抽取一个数据, 将末位数据放入被抽取位置. 同时将抽取范围-1 要用多少个随机数就抽多少次. 永远不会重复, 而且每次抽取只需要两次赋值操作就可以进行下一次抽取. 也根本不会重复. 连比较都是多余的.
关键是这个数组太大了。没法在电脑上实现。 [/quote] 这样看来,就得专门建一个数组或表来记录已经被抽取过的位置的新值了. 这个用于维护的数组或表是递增的, 最大数量为99999999. 不过这样一来, 程序就会变得很难看. 效率也无法保证.
  • 打赏
  • 举报
回复
引用 180 楼 WallesCai 的回复:
直接从一个16位数的顺序数组中随机位置抽取数据, 每抽取一个数据, 将末位数据放入被抽取位置. 同时将抽取范围-1 要用多少个随机数就抽多少次. 永远不会重复, 而且每次抽取只需要两次赋值操作就可以进行下一次抽取. 也根本不会重复. 连比较都是多余的.
关键是这个数组太大了。没法在电脑上实现。
熊孩子开学喽 2014-10-06
  • 打赏
  • 举报
回复
直接从一个16位数的顺序数组中随机位置抽取数据, 每抽取一个数据, 将末位数据放入被抽取位置. 同时将抽取范围-1 要用多少个随机数就抽多少次. 永远不会重复, 而且每次抽取只需要两次赋值操作就可以进行下一次抽取. 也根本不会重复. 连比较都是多余的.
  • 打赏
  • 举报
回复
引用 楼主 sysdzw 的回复:
我的方法是借助于数据库的。数据库表的字段设置主键后插入重复数据会提示失败,我就写了个程序不断地往数据库里插入数据,遇到主键重复错误就忽略。代码如下:
Private Sub Command1_Click()
    Dim s$
    Dim i As Single, sng1 As Single
    Dim j%
    On Error resume next'当数据库主键字段v_no有重复的时忽略错误
    For i = 1 To 10000000
        s = ""
        For j = 1 To 16'生成随机16位数
            Randomize
            s = s & Mid("0123456789", Int(Rnd * 9) + 1, 1)
        Next
        Me.Caption = i & " " & s: DoEvents
        conn.Execute "INSERT INTO verify(v_no)  VALUES('" & s & "')"
    Next
End Sub
我用上述方法生成发现最多也就生成100万个不同的数据。循环一千万次。 当重复执行后,也就是再循环1000万次,数据也就多了一两万而已。 重复的太多!! 怎样最快速的生成呢?? 现在来看这个方法不可行,半个小时了才多几百个新的随机16位数据。
楼主,我觉得比较奇怪的是,值域是10^16这么多数,而只要生成10^7个。差了10^9个数量级。怎么会重复那么多?? 我在[1~100000]的范围内取100个随机数(范围是千分之一)。试验了100次,其中只有5次出现了重复(重复以后再补生成若干个)。 BTW,双色球一等奖的概率是1/17721088,数量级是10^7。而“差了10^9个数量级”,如果发生个别重复已经是‘极小概率’事件了!而运行时才生成1百万个就发生大规模的重复,好像不可能? 所以, ①会不会是数据库误报呢?看一看Err的具体号码和描述??看一看此时生成的数据,是不是真的和数据库已有的重复?“接口”的问题?同步异步什么的?(DoEvents这一行屏蔽一下?可能降低很多速度。或者每10万次做一下。)还有,这句话我不懂:VALUES('" & s & "'),看上去像字符串连接?VB里面,好像字符串连接到一定长度以后就非常慢了。。。还有,数据库的容量什么的? ②两个变量single类型,改为double试试?好像single的有效数字只有7位?超过的话会被用E指数处理成接近的数,可能引起程序错误。 ③Randomize,改为Randomize(i+j+timer+句柄)试试?(不知道Rnd函数的周期性是多少??) ④好像你这个句子写错了:s = s & Mid("0123456789", Int(Rnd * 9) + 1, 1) mid函数:Mid(string, start[, length])。此处,start应该从1到10。 而,生成某个范围内[左右都是闭区间]的随机整数:Int((upperbound - lowerbound + 1) * Rnd + lowerbound) 应该是:Int((10 - 1 + 1) * Rnd + 1) = Int(10 * Rnd + 1) 你的写法:Int(Rnd * 9) + 1。取值是[1,9] 所以你取的是"012345678"。你可以看看生成的数据,里面有没有"9"? 虽然仍然是16位,但是里面没有"9",每位的取值是9种可能,此时值域共有9^16个,等于 1.853*10^15 。 这仍然是一个非常大的值域。所以,还是不应该发生这么多重复,呵呵。 仅供参考。
  • 打赏
  • 举报
回复
引用 6 楼 caozhy 的回复:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var obj = new GenDec16();
            foreach (var item in obj)
            {
                Console.WriteLine(item);
            }
        }
    }

    class GenDec16 : IEnumerator, IEnumerator<string>, IEnumerable<string>
    {
        class Tree
        {
            public Tree(int Length)
            {
                node = new Node(0, Length);
            }
            Node node;

            public string GenNewValue() { return node.GenNewValue(); }

            public bool HasNewValue
            {
                get
                {
                    return node.HasNewValue;
                }
            }
        }

        class Node
        {
            static Random rnd = new Random();

            public Node(int id, int level)
            {
                ID = id;
                Level = level;
                HasNewValue = true;
                if (level > 0) ChildNodes = new List<Node>();
            }

            public override string ToString()
            {
                return string.Format("{0}: childs={1}, hasnew={2}.", 
                    ID, 
                    string.Join(",", ChildNodes.Select(x => x.ID).OrderBy(x => x)), 
                    HasNewValue);
            }

            public int ID { get; set; }
            public bool HasNewValue { get; set; }
            public int Level { get; set; }
            List<Node> ChildNodes { get; set; }

            public string GenNewValue()
            {
                string result = "-";
                if (Level == 0)
                {
                    result = "";
                    HasNewValue = false;
                }
                else
                {
                    do
                    {
                        int n = Node.rnd.Next(0, 10);
                        var node = ChildNodes.SingleOrDefault(x => x.ID == n);
                        if (node == null)
                        {
                            node = new Node(n, Level - 1);
                            ChildNodes.Add(node);
                        }
                        if (!node.HasNewValue) continue;
                        result = n.ToString() + node.GenNewValue();
                    } while (result == "-");
                    HasNewValue = ChildNodes.Count != 10 || ChildNodes.Any(x => x.HasNewValue);
                }
                return result;
            }
        }

        Tree tree;

        public GenDec16()
        {
            (this as IEnumerator).Reset();
        }

        object IEnumerator.Current
        {
            get { return tree.GenNewValue(); }
        }

        bool IEnumerator.MoveNext()
        {
            return tree.HasNewValue;
        }

        void IEnumerator.Reset()
        {
            tree = new Tree(16); //16位
        }

        string IEnumerator<string>.Current { get { return tree.GenNewValue(); } }

        void IDisposable.Dispose()
        {
            
        }

        IEnumerator<string> IEnumerable<string>.GetEnumerator()
        {
            return this;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
    }
}
贴一个我写的代码给你,跑1千万,大约需要1分钟。当然需要把输出去掉。
请问这段代码是生成并检验重复吗?(我不懂C语言)。1分钟是什么结果?生成一千万?,没有重复的?
  • 打赏
  • 举报
回复
引用 175 楼 quanxusheng 的回复:
前面有网友说了洗牌算法。我补充一些。 用某一种“洗牌”算法来实现“生成10000万个随机的不同16位数”、而且楼主是需要不重复的。(是否“最快”?我不懂怎么证明最快。)..............
看到了这个帖子:http://bbs.csdn.net/topics/10196759 VB数组的上下界从-2G到2G,就是,最多4G个元素(10^9)。所以直接生成[0,10^16-1]的数组肯定不行。不知道有什么变通的方法?而且,大数组(数组元素个数*数组的类型的长度)可能远远超过了内存允许的范围! 另外发现一个问题,如果VB程序(编译为‘本机代码’的exe文件)占用大量的虚拟内存(硬盘上),WindowsXP会自动降低程序的运行速度?本来在内存中应该是占满CPU的,此时CPU很空,这样程序就跑的非常慢,可能要几十倍的处理时间。。。。。不是VB写的程序有类似的问题吗?
一如既往哈 2014-10-02
  • 打赏
  • 举报
回复
一次性需要这么多的随机数,楼主的要求还真是挺特别的.....
  • 打赏
  • 举报
回复
前面有网友说了洗牌算法。我补充一些。 用某一种“洗牌”算法来实现“生成10000万个随机的不同16位数”、而且楼主是需要不重复的。(是否“最快”?我不懂怎么证明最快。) 借用某一种洗牌算法,这种洗牌算法已经被证明是随机的。(是否更接近于“真正随机”,取决于那个具体的random函数本身。这种洗牌算法本身是真正随机的,据介绍是被证明过的。) 这种洗牌算法是: for i:=1 to n do swap(a[i], a[random(i,n)]);(注意random的范围是i到n,不是1到n。) 16位数,相当于[0,10^16-1]。 用这个范围代替一般‘洗牌’的[1,54]。vb里面建立一个相应的数组(如果取值范围是海量的话,是否超过vb的数组上限及内存什么的,暂不考虑)。需要10000万个(即10^8个),那么就只要执行10000万次,得到10000万个“swap之后的a[i]”。就符合楼主的要求了。(需要的话,用format函数再处理一下,补足前导的0。)
chuifengde 2013-09-26
  • 打赏
  • 举报
回复
引用 168 楼 Chen8013 的回复:
[quote=引用 167 楼 chuifengde 的回复:] 数据库中用checksum+newid生成100万随机数16位纯数字大概30秒
我们1000万还不到15秒。 你算算,照你那样生成1000万条,得要多久了? 顺便说一下的是,156F的方法,是不符合楼主的要求的。 我后来想到一个方案,解决了在164F所说的“分4组”的问题, 可以在“自己的编号”中管理 约86亿个(85.89亿) 数据编号了。 如果用数据库配合进行一下“分段管理”,在比较低的重复率下,估计就是生成几百亿条甚至1千亿条数据,难度都不大。 (检测到重复,可以重新生成,毕竟重复率低,生成新数据也很容易。) 只是看到楼主自己好象都没管这事了,我也不想多说什么。 [/quote] 这个是跟环境有关系的,还可以优化
1974n 2013-09-25
  • 打赏
  • 举报
回复
原来是这样子。
haitao 2013-09-24
  • 打赏
  • 举报
回复
引用 171 楼 Chen8013 的回复:
我不知道你在156F的数据是怎么来的,那么长一串,后面部分倒是乱的。 但楼主要求的是:16位数字(注意:只是10进行数字,也就是0到9) 你要是生成的结果按什么“时间”来,必然看起来象连续号码。
左边不乱的16进制,只是演示了右边乱的10进制(只是数字,也就是0到9)是怎么来的:它们是同样的二进制内容 既然你都说它(右边)乱了,也就是不象连续号码,说明已经满足lz的要求了 我在169楼只是说它还可以更乱,甚至与des加密差不多的乱
舉杯邀明月 2013-09-24
  • 打赏
  • 举报
回复
我不知道你在156F的数据是怎么来的,那么长一串,后面部分倒是乱的。 但楼主要求的是:16位数字(注意:只是10进行数字,也就是0到9) 你要是生成的结果按什么“时间”来,必然看起来象连续号码。
舉杯邀明月 2013-09-24
  • 打赏
  • 举报
回复
你仔细看楼主在前面是怎么说的吧。
haitao 2013-09-24
  • 打赏
  • 举报
回复
引用 168 楼 Chen8013 的回复:
[quote=引用 167 楼 chuifengde 的回复:] 数据库中用checksum+newid生成100万随机数16位纯数字大概30秒
我们1000万还不到15秒。 你算算,照你那样生成1000万条,得要多久了? 顺便说一下的是,156F的方法,是不符合楼主的要求的。 [/quote] 为什么不符合? “乱”的不够? 我这次只是加入一个字节,如果分成每位加到8个位置,会乱得更厉害 乱到极致,就类似des加密的结果了
舉杯邀明月 2013-09-24
  • 打赏
  • 举报
回复
引用 167 楼 chuifengde 的回复:
数据库中用checksum+newid生成100万随机数16位纯数字大概30秒
我们1000万还不到15秒。 你算算,照你那样生成1000万条,得要多久了? 顺便说一下的是,156F的方法,是不符合楼主的要求的。 我后来想到一个方案,解决了在164F所说的“分4组”的问题, 可以在“自己的编号”中管理 约86亿个(85.89亿) 数据编号了。 如果用数据库配合进行一下“分段管理”,在比较低的重复率下,估计就是生成几百亿条甚至1千亿条数据,难度都不大。 (检测到重复,可以重新生成,毕竟重复率低,生成新数据也很容易。) 只是看到楼主自己好象都没管这事了,我也不想多说什么。
chuifengde 2013-09-24
  • 打赏
  • 举报
回复
数据库中用checksum+newid生成100万随机数16位纯数字大概30秒
haitao 2013-09-07
  • 打赏
  • 举报
回复
随机是想对什么人? 156楼的序号,十进制部分,对于普通用户,也足够随机了
舉杯邀明月 2013-09-06
  • 打赏
  • 举报
回复
今天下午写段代码试验了下,发现一个问题: 9位十进制数序号,要用30位二进制数; 但在30位二进制数的大数部分,有10位数了。  因此还是得用10位序号。 这样就只能用: 序号(10位)+随机数(4位)+校验码&补0数(2位) 容量是21亿条数据(校验码&补0数 中的部分值为100~121,已经成功“转移”到了100以下来存储)。 后来经“深挖潜力”后,可以达到40亿(或42亿)条数据容量(增加1个组标记,跟序号组合在一起)。 这个反复思考过,只能有2个组。 要是能解决 “0~15的值只存个位、并且能原”的问题,则可以分4组,能达到80亿条(或84亿条)了。 我也写了段代码验证,发现只存个数的值,有时候无法还原。 (楼主可以看下我后面的描述,看能不能解决还原问题) 分4个组的情况是这样的: 就是10位十进制序号,基最高位的值只可能是0、1、2,二进制只用2位; 组序号是 0~3 ,也只要2位二进制数。 如果把它们组合在一个字节中,十进制序号放高位,组序号放低位,这样就是 0000 ~ 1011 。 这样就遇到了有2个值无法用1位十进制数来存放: 1010、1011。 并且这个组合的随机性不是很好:一段连续的序号,组号基本是相同的(这样那一位就常在3个值之间跳动)。 如果让它与另一个数异或(值随机的,在串序号中某固定位置取),那它的范围就是 0000 ~ 1111 了。
加载更多回复(129)

7,763

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧