从 string 字符串中随机提取字符,组成指定长度的新字符串问题。

2023-02-05 23:39:37 +08:00
 qazwsxkevin
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string>

using namespace std;

int main(int argc, char **argv)
{
    string allcode = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
   
    srand(time(NULL));
    
    int l = 8; //指定的新字符串长度
    string s;  //新组成的随机字符串
    char cc;   //被抽中的字符
    
    for (int i=0;i<l;i++)
    {
        srand(time(NULL));
        int randNum = rand() % allcode.length();
        cc = letters[randNum];
        s = s + cc;
    }
    cout << s << endl;
    
    // 为啥 s 是一串重复的字符串?

另外一个问题是,观察到 srand(time(NULL))的值是 1 秒内不会变的(在我用的电脑和系统上是这样),
如果一秒内有很多次循环,这个似乎不太好,应该如何更“真”的保证和上次循环有不同随机?

1664 次点击
所在节点    C++
6 条回复
qazwsxkevin
2023-02-05 23:42:12 +08:00
by the way ,原本是 python 做这个的,速度有些慢,所以临时找了大学时候的 Dev-C++绿色版搭配旧 GCC 3.4.2 版本,把 python 脚本转成 C++来完成这个事情,C++11 是没有的。。。
wevsty
2023-02-05 23:50:18 +08:00
srand 只调用一次不需要每次循环都重设 srand 。

如果需要真随机数或者用于加密学等用途请使用平台提供的 API 或者 STL 抽象出来的 std::random_device 。
但既然不支持 CPP11 ,那么你就只能选择使用平台提供的 API 了。
AzadCypress
2023-02-06 00:44:27 +08:00
因为 time(null)返回的是 从 1970 年到现在的 秒数 ,用同一个 seed 初始化的序列肯定是一样的
srand 一般只调用一次,把 for 循环里的 srand 删除就好了
qazwsxkevin
2023-02-06 00:55:55 +08:00
明白了,所以,
有啥办法,保证 1 秒内能拿 1 万个不同的种子呢?
cnbatch
2023-02-06 03:18:22 +08:00
最佳做法就是换新的编译器( MSVC 或者 GCC 或者 Clang 均可),使用 C++11 的 std::random_device
(等待答案的这段时间,足够用来下载新版本了)

cppreference 连示例都列出来了
https://en.cppreference.com/w/cpp/numeric/random/random_device/random_device
照抄就能用,只需要按照实际需求改一改 d(0, 9) 的范围就可以了

顺便扩充点内容:
cppreference 给出的这段 demo 用了 4 种不同的 std::random_device 初始化版本,对于 MSVC 而言全都一样,初始化参数会自动忽略掉(我猜也许 GCC 和 Clang 在 Windows 都是一样的,若要确定那就需要查源码,我懒得查了),微软自己的文档就有提到‘the values produced are non-deterministic and cryptographically secure, but runs more slowly than generators created from engines and engine adaptors’
https://learn.microsoft.com/en-us/cpp/standard-library/random-device-class?view=msvc-170
似乎在暗示 MSVC 的 std::random_device 会尽可能调用硬件生成器
piku
2023-02-06 09:14:47 +08:00
Python 慢?试了一万行 8 随机字母只有 0.128 秒

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/913440

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX