C++ srand()只能调用一次,否则rand()每次返回相同值

2023-11-11

C++ srand()只能调用一次,否则rand()每次返回相同值

面试的时候写一个洗牌算法,结果遇到这个问题坑死我了,幸运的是面试官也不太看得出来问题出在哪(他主攻Java),所以给了我足够时间去调试……


问题描述:

自己创作的洗牌算法:

#include <iostream>
#include <ctime>
using namespace std;
int GetRandomNumber()
{
    int RandomNumber;
    srand((unsigned)time(0));//time()用系统时间初始化种。为rand()生成不同的随机种子。
    RandomNumber = rand() % 100 + 1;//生成1~100随机数
    return RandomNumber;
}
void getRand(int* arr)
{
    int i, j, temp;
    for (i = 0; i < 100; ++i)
    {
        j = GetRandomNumber();
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    return;
}
int main() {
    int a[100], i;
    for (i = 0; i < 100; ++i)
        a[i] = i + 1;
    getRand(a);
    for (i = 0; i < 100; ++i)
        cout << a[i] << ' ';
}

结果实际运行结果却是这样的:
结果1
结果2
也就是说只交换了第一个数字,这让我百思不得其解。


原因分析:

于是我询问面试官能否用编译器调试(面试时手撕代码),他问我除了编译器还有什么好的方法,我想到了用cout输出每个变量,看看问题发生在哪。当我输出每次产生的随机数 j 的时候,问题就浮出水面。
随机数每次都是一样的
于是我就怀疑是不是因为每次调用GetRandomNumber都用了srand函数进行初始化种子。然后因为整个程序运行的时间很短,初始化种子用的系统时间单位是秒,意味着种子是相同的,每次都把伪随机序列初始化成相同的序列,因此每次调用rand返回的都是序列的第一个值,因此是相同的值。
当时面试也管不了那么多,只能把srand改成初始化一次,确实就可以正常运行了。
事后参考相关资料得知srand设置随机生成器的状态,得到一大串序列(通常是4,294,967,296),然后调用rand每次从序列中取第一个,取完塞回序列尾端,之后取第二个、第三个就可以做到伪随机的效果。
因此我的问题就在于每次获取随机数都初始化了队列,在不到一秒的运行时间内这些序列都是相同的。而每次rand都取队列第一个数字,所以每次返回的值都相同。


解决方案:

将代码修正成如下所示即可,总之srand初始化调用一次就行了,之后每次用rand就可以输出伪随机数。否则rand就会一直返回相同的值!

#include <iostream>
#include <ctime>
using namespace std;
void getRand(int* arr)
{
    int i, j, temp;
    srand((unsigned)time(NULL));
    for (i = 0; i < 100; ++i)
    {
        j = rand() % 100;
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    return;
}
int main()
{
    int a[100], i;
    for (i = 0; i < 100; ++i)
        a[i] = i + 1;
    getRand(a);
    for (i = 0; i < 100; ++i)
        cout << a[i] << ' ';
}

参考资料:https://www.imooc.com/wenda/detail/558945

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ srand()只能调用一次,否则rand()每次返回相同值 的相关文章

  • EF Core Group By 翻译支持条件总和

    听说 EF Core 2 1 将支持翻译小组 我感到非常兴奋 我下载了预览版并开始测试它 但发现我在很多地方仍然没有得到翻译分组 在下面的代码片段中 对 TotalFlagCases 的查询将阻止翻译分组工作 无论如何 我可以重写这个以便我
  • C 编程 - 文件 - fwrite

    我有一个关于编程和文件的问题 while current NULL if current gt Id Doctor 0 current current gt next id doc current gt Id Doctor if curre
  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • 我如何才能等待多个事情

    我正在使用 C 11 和 stl 线程编写一个线程安全队列 WaitAndPop 方法当前如下所示 我希望能够将一些内容传递给 WaitAndPop 来指示调用线程是否已被要求停止 如果 WaitAndPop 等待并返回队列的元素 则应返回
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • 查找c中结构元素的偏移量

    struct a struct b int i float j x struct c int k float l y z 谁能解释一下如何找到偏移量int k这样我们就可以找到地址int i Use offsetof 找到从开始处的偏移量z
  • 为什么当实例化新的游戏对象时,它没有向它们添加标签? [复制]

    这个问题在这里已经有答案了 using System Collections using System Collections Generic using UnityEngine public class Test MonoBehaviou
  • 类模板参数推导 - clang 和 gcc 不同

    下面的代码使用 gcc 编译 但不使用 clang 编译 https godbolt org z ttqGuL template
  • 在 Windows 窗体中保存带有 Alpha 通道的单色位图会保存不同(错误)的颜色

    在 C NET 2 0 Windows 窗体 Visual Studio Express 2010 中 我保存由相同颜色组成的图像 Bitmap bitmap new Bitmap width height PixelFormat Form
  • 不同枚举类型的范围和可转换性

    在什么条件下可以从一种枚举类型转换为另一种枚举类型 让我们考虑以下代码 include
  • 在 ASP.NET 5 中使用 DI 调用构造函数时解决依赖关系

    Web 上似乎充斥着如何在 ASP NET 5 中使用 DI 的示例 但没有一个示例显示如何调用构造函数并解决依赖关系 以下只是众多案例之一 http social technet microsoft com wiki contents a
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • 如何在Python中对类别进行加权随机抽样

    给定一个元组列表 其中每个元组都包含一个概率和一个项目 我想根据其概率对项目进行采样 例如 给出列表 3 a 4 b 3 c 我想在 40 的时间内对 b 进行采样 在 python 中执行此操作的规范方法是什么 我查看了 random 模
  • 带动态元素的 WPF 启动屏幕。如何?

    我是 WPF 新手 我需要一些帮助 我有一个加载缓慢的 WPF 应用程序 因此我显示启动屏幕作为权宜之计 但是 我希望能够在每次运行时更改屏幕 并在文本区域中显示不同的引言 这是一个生产力应用程序 所以我将使用非愚蠢但激励性的引言 当然 如
  • 转发声明和包含

    在使用库时 无论是我自己的还是外部的 都有很多带有前向声明的类 根据情况 相同的类也包含在内 当我使用某个类时 我需要知道该类使用的某些对象是前向声明的还是 include d 原因是我想知道是否应该包含两个标题还是只包含一个标题 现在我知
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 如何使用 C# / .Net 将文件列表从 AWS S3 下载到我的设备?

    我希望下载存储在 S3 中的多个图像 但目前如果我只能下载一个就足够了 我有对象路径的信息 当我运行以下代码时 出现此错误 遇到错误 消息 读取对象时 访问被拒绝 我首先做一个亚马逊S3客户端基于我的密钥和访问配置的对象连接到服务器 然后创
  • 混合 ExecutionContext.SuppressFlow 和任务时 AsyncLocal.Value 出现意外值

    在应用程序中 由于 AsyncLocal 的错误 意外值 我遇到了奇怪的行为 尽管我抑制了执行上下文的流程 但 AsyncLocal Value 属性有时不会在新生成的任务的执行范围内重置 下面我创建了一个最小的可重现示例来演示该问题 pr
  • 如何在文本框中插入图像

    有没有办法在文本框中插入图像 我正在开发一个聊天应用程序 我想用图标图像更改值 等 但我找不到如何在文本框中插入图像 Thanks 如果您使用 RichTextBox 进行聊天 请查看Paste http msdn microsoft co

随机推荐

  • 复习:最短路径

    一 基本概念 最短路径 在非网图中 最短路径是指两顶点之间经历的边数最少的路径 在网图中 最短路径是指两顶点之间经历的边上权值之和最少的路径 源点 路径上的第一个顶点 终点 路径上最后一个顶点 二 Dijkstra算法 只适用于简单路径 不
  • 最小生成树,Prim算法与Kruskal算法,408方向,思路与实现分析

    最小生成树 Prim算法与Kruskal算法 408方向 思路与实现分析 最小生成树 老生常谈了 生活中也总会有各种各样的问题 在这里 我来带你一起分析一下这个算法的思路与实现的方式吧 在考研中呢 最小生成树虽然是只考我们分析 理解就行 但
  • NestedScrollView嵌套RecyclerView只显示一行的问题

    1 添加属性设置 设置布局管理器 LinearLayoutManager linearLayoutManager new LinearLayoutManager context linearLayoutManager setOrientat
  • node写可选参数接口

    个人网站 紫陌 笔记分享网 想寻找共同学习交流 共同成长的伙伴 请点击 前端学习交流群 今天写项目接口看到接口文档要求带四个参数两个参数必选两个可选 当时在想可选参数要怎么做 毕竟自己也没有写过 然后想了一天终于想出一个感觉不是最佳的方案
  • 极简教学

    目录 一 安装wget 二 安装git 三 安装pip 四 下载ChatGLM2 6B源码 五 安装Anaconda 六 安装pytorch 七 下载模型库 八 最后的准备工作 九 运行程序 一 安装wget 1 删除自带的wget yum
  • CAN总线的EMC设计方案

    一 CAN接口EMC设计概述 Controller Area Network简称为CAN 多用于汽车以及工业控制 用于数据的传输控制 在应用的过程中通讯电缆容易耦合外部的干扰对信号传输造成一定的影响 单板内部的干扰也可能通过电缆形成对外辐射
  • kafka多线程实现消费者实战

    前言 KafkaProducer是线程安全的 但是KafkaConsumer不是线程安全的 同一个KafkaConsumer用在了多个线程中 将会报Kafka Consumer is not safe for multi threaded
  • emplace_back和push_back的区别

    相同点 两者都是向容器内添加数据 不同点 当数据为类的对象时 emplace back相对push back可以避免额外的移动和复制操作 以下代码copy from点击打开链接 include
  • LeetCode-917. 仅仅反转字母

    给你一个字符串 s 根据下述规则反转字符串 所有非英文字母保留在原有位置 所有英文字母 小写或大写 位置反转 返回反转后的 s 示例 1 输入 s ab cd 输出 dc ba 来源 力扣 LeetCode 双指针 双指针是一种解决问题的技
  • C++中的虚函数(一)

    虽然很难找到一本不讨论多态性的C 书籍或杂志 但是 大多数这类讨论使多态性和C 虚函数的使用看起来很难 我打算在这篇文章中通过从几个方面和结合一些例子使读者理解在C 中的虚函数实现技术 说明一点 写这篇文章只是想和大家交流学习经验因为本人学
  • 互联网项目生产线各环节介绍

    采用敏捷开发模式 每个周期为两周 每次完成5 10个不等的story 然后进入下一个迭代 以此类推 1 需求管理 这个由产品部来负责收集 分析 整理 最终形成一个个可进行开发的story 需求管理工具选用icescrum 2 代码研发 由j
  • flutter image_picker 控件的使用 ---选择系统图片、拍照

    在pubspec yaml中添加依赖 dependencies image picker 0 4 12 1 Dart文件如下 import package flutter material dart import package image
  • CTF_ctfshow_meng新_web1-web24

    打开靶机 发现包含有个config php文件 打开进去没有数据 所以直接开始代码审计吧 有个变量为id 参数必须为1000才能获得flag 但id gt 999直接返回退出了 尝试一下sql注入 整形注入 看一下回显点 回显点为三 版本
  • LTV-MPC

    For compatibility with the adaptive mode the plant model specified in your controller object must be LTI state space OK
  • java中文档注释的标记是_javadoc中文档注释标记的使用

    javadoc中文档注释标记的使用 author 标记 author指定一个类的作者 它的语法如下 author description 其中 description通常是编写这个类的作者名字 标记 author只能用在类的文档中 在执行j
  • PCL 改进体素滤波

    一 改进简介 PCL的VoxelGrid类是通过输入的点云数据创建一个三维体素栅格 用每个体素内用体素中所有点的重心来近似显示体素中的其他点 这样该体素内所有点都用一个重心点来最终表示 该重心点不一定就是原始点云中的点 有失原始点云的细小特
  • 用c语言浮点输出时,如何让小数点后没用的0不显示

    动态控制浮点数小数位数 2020年7月29日 存在问题 C语言把浮点数直接通过sprintf函数保存在字符数组中 末尾的0显得很多余 想办法把末尾的0去掉 解决问题 在打印时 通过格式控制输出 一般情况使用 f即可输出浮点数 我们通过 f
  • linux查看3306是哪个进程占用,linux查看端口占用

    发表于 2019 08 18 21 00 36 by 月小升 一 例子 lsof i 7000 COMMAND PID USER FD TYPE DEVICE SIZE OFF NODE NAME frps 1249 root 3u IPv
  • 二叉树代码

    1 普通二叉树的构建 构建结点以及搜索与删除的方法 public class Node private int no private String name private Node left private Node right priv
  • C++ srand()只能调用一次,否则rand()每次返回相同值

    C srand 只能调用一次 否则rand 每次返回相同值 面试的时候写一个洗牌算法 结果遇到这个问题坑死我了 幸运的是面试官也不太看得出来问题出在哪 他主攻Java 所以给了我足够时间去调试 问题描述 自己创作的洗牌算法 include