人人都能学会的编程入门课
胡光
原百度高级算法研发工程师
19410 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 38 讲
开篇词 (1讲)
人人都能学会的编程入门课
15
15
1.0x
00:00/00:00
登录|注册

04 | 随机函数:随机实验真的可以算 π 值嘛?

你好,我是胡光。上次课里关于判断和循环的内容你做练习了么?其实这两部分内容都不复杂,你想,判断就是“如果…就…”,而循环就是重复做一件事情。程序里,只是我们换了一种方式来描述和抽象这两个场景。

今日任务

今天的任务其实也是和上次讲的内容有很大关系。如果你对上次讲的内容不理解,我建议你先再好好回顾下上次讲的知识,然后开始今天的任务。
先来看看今天这 10 分钟我们要完成的任务。圆周率 π 对你来说肯定不是一个陌生的概念,它指的是圆的周长与直径的比值。在古代,数学家们为了计算 π 的精确值想尽方法,可能穷尽一生也不过精确到小数点后几位而已。但到了现在,你可能不相信,只要你知道 π 的定义,就可以利用编程轻易计算出 π 的值。那究竟怎么做到呢?
我们先来看一个用蒙特卡罗法计算 π 的示意图:
图1:蒙特卡罗法示意图
通过观察图 1,请你思考一个问题,如果你随机地在正方形区域中选择一个点,那么这个被选择的点,也恰巧落在圆形红色区域的概率是多大?这个问题很简单,就是圆面积和正方形面积的比值,简单计算就可以得到这个概率值,应该是 π/4。
也就是说,如果我们做大量的随机实验,最终落在圆内部的次数除以总次数再乘以 4 得到的值,应该接近圆周率 π。随机次数越多,所得到的数值越接近 π。你肯定不喜欢做这种重复的“重体力”劳动,但如果你写好编程,让它帮你做这件事,那就简单容易快捷多了。计算机可是一个不怕辛苦、没有怨言的好帮手,今天就让它来帮助我们完成这个任务吧。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了使用随机函数计算圆周率 π 的方法。首先介绍了 π 的定义和古代数学家们为了计算 π 的精确值所做的努力。随后引入了蒙特卡罗法,通过大量的随机实验来计算 π 的值。文章还介绍了真随机和伪随机的概念,以及在 C 语言中使用随机函数的方法。最后,提出了一个思考题,要求设计一个迷你随机函数,循环输出 1~100 中的每个数字,但要求输出的规律不太明显。通过本文的介绍,读者可以了解到随机函数的概念和在计算 π 值中的应用,以及如何在程序中使用随机函数进行随机数生成。文章内容生动有趣,通过实例代码展示了随机函数的应用,对读者进行了技术知识的传授和思维能力的锻炼。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《人人都能学会的编程入门课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(43)

  • 最新
  • 精选
  • 栾~龟虽寿!
    老师很厉害,才4节课你就会看到,老师想说,学编程,为做事高效,为生活添彩,如果你不断重复,成功概率会变化。

    作者回复: d(^_^o) 你这总结的太棒了,我得记下来!

    2020-01-12
    8
  • rocedu
    rand实现用的公式给一下,更能说明伪随机性。

    作者回复: int __cdecl rand ( void ) { _ptiddata ptd = _getptd(); return( ((ptd->_holdrand = ptd->_holdrand * 214013L + 2531011L) >> 16) & 0x7fff ); }

    2020-02-02
    7
  • Noya
    老师, 计算机中的随机其实就是一个循环的序列对吗, 然后每次过去一个, 就"随机"了

    作者回复: 对的。这个序列很大,我们不可知,所以对于我们来说,跟随机没啥区别。

    2020-04-28
    4
  • 点金
    思考题: #include <stdio.h> int main(){ int n=5; for (int i=1;i<=100;++i){ printf("%3d",n); if (i%10==0) printf("\n"); n*=3; while (n>100) n-=102; } return 0; } 按老师的提示程序是写出来了,不过还是有几个疑问: 1、这个规律的正确性如何证明,即这个函数如何做到遍历100个数不遗漏且不重复; 2,可否把每次扩大的倍数由3改成其它值,如果可以的话,超出100后,每次又要减去什么数了呢? 3、扩大的倍数可以是哪些值,我目前能想到的是肯定不能是100的因数

    作者回复: 可以的。正确性证明的话,需要有一些数论基础知识作支撑,例如:欧拉函数,费马小定理及欧拉定理。

    2020-04-04
    2
    2
  • Jinlee
    老师您好,为啥我的结果里面有重复的数字呢 #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int i, j; srand(time(0)); //初始化随机数种子 for (i = 1, j = 1; i <= 100; i++, j++) { printf("%d\t", 1+rand() % 100); if (j % 10 == 0) printf("\n"); } system("pause"); return 0; }

    作者回复: 当然会有重复数字了,因为你对rand的结果取余了。rand的循环长度可能很大,可取余100以后,就很容易出现重复啊。就比如101和100001取余100,不都是1么。

    2020-01-14
    2
    2
  • 小风
    老师这个随机函数那个RAND_MAX是什么概念,怎么用的呢

    作者回复: 这个 RAND_MAX 你可以认为是一个和编译环境相关的数字,后面讲完宏以后,你就可以理解了,其实这就是一个宏。平时基本不用这个东西,对这个东西有个基本的概念即可。

    2020-05-01
    1
  • 罗耀龙@坐忘
    茶艺师学编程 思考题:设计一个循环过程,循环 100 次,以不太明显的规律输出 1~100 中的每个数字。 在这里,我遇到的坑: 1、随机生成了一个数,重复了100次; 2、能随机生成了不一样的数字,但数字数量是101个; 最后我能实现的,是按要求生成了100个范围在(1,100)的随机数,且做到每次运行都不一样。 这是代码: #include <stdio.h> #include <stdlib.h> //srand(),rand()需要的说明 ,好像time也要这个 #include <time.h> //time()必要的说明 int main(){ srand(time(0)); //这里保证我每次运行程序得出的随机数都不一样 ,用时间函数作为随机种子 for (int i = 0;i<100;i++){ int X = 99 * rand()/RAND_MAX + 1; //目标是1-100之间的整数,而RAND_MAX取值范围是0到最大值,0-99正好就是100个数字 printf("%d\t",X); } return 0 ; }

    作者回复: 可以参考我后面文章中的答案。

    2020-04-24
    1
  • 落曦
    作业 #include <stdio.h> #include <stdlib.h> #include <time.h> int main() { int i; for(i=0;i<100;i++) printf("%d\t", rand() % 100); // 永远输出固定值 return 0; }

    作者回复: 仔细看作业要求,要求是输出100次,不重不漏的输出1--100中的数字。

    2020-03-27
    2
    1
  • Geek_29429b
    请教老一个问题,这是我照书上写的一个程序,但我不知道怎么测试这个程序是否正确,因为当我执行这个程序后,在控制台无论输入什么,都不会执行printf()方法: #include <stdio.h> /* 统计各个数字、空白符及其他字符出现的次数 */ int main() { int c, i, nwhite, nother; int ndigit[10]; nwhite = nother = 0; for (i = 0; i < 10; ++i) ndigit[i] = 0; while ((c = getchar()) != EOF) if (c >= '0' && c <= '9') ++ndigit[c - '0']; else if (c == ' ' || c == '\n' || c == '\t') ++nwhite; else ++nother; printf("digits ="); for (i = 0; i < 10; ++i) printf(" %d", ndigit[i]); printf(", white space = %d, other = %d\n", nwhite, nother); return 0; }

    作者回复: 结束条件是读入到文件末尾结束,也就是那个不等于EOF的判断。所以无论你输入什么内容,都是正常的内容,都不是EOF,程序也就都不会结束。你需要搜索在你的环境中如何输入EOF,一般是ctrl+z

    2020-02-14
    1
  • rocedu
    "记住,计算机就是你的小帮手了,以后的日子里,请动用你的智力,使用它的体力!"这真说出了为何人人都需会点编程。

    作者回复: d(^_^o)

    2020-02-03
    1
收起评论
显示
设置
留言
43
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部