图源:文心一言
听课笔记简单整理,包括以下内容”🐋3.2 二进制转十进制、🐋3.3 数学公式1:用反切函数表示pi、🐋3.4 判断回文数、🐋3.5 数学公式2:分段函数、🐋3.6 扔骰子“供小伙伴们参考~🥝🥝
- 第1版:听课的记录代码~🧩🧩
编辑:梅头脑🌸
审核:文心一言
目录
🐳课程来源
🐳函数调用
🐋3.2 二进制转十进制
🐋3.3 数学公式1:用反切函数表示pi
🐋3.4 判断回文数
🐋3.5 数学公式2:分段函数
🐋3.6 扔骰子
🔚结语
🐳课程来源
- 郑莉老师的公开课:🌸C++语言程序设计基础 - 清华大学 - 学堂在线 (xuetangx.com)
备注:本章中的sin()、arctan()、power()在C++库中均可以直接调用,为了练习,老师要求这些函数均为手打。
🐳函数调用
🐋3.2 二进制转十进制
📇算法思路
- 输入8位二进制数,每位数字乘以其权值相加(在本栗中,这个功能由函数power完成),即为十进制;
- 举栗:01101001为二进制,转十进制的算式:0 x 2^7 + 1 x 2^6 + 1 x 2^5 + 0 x 2^4 + 1 x 2^3 + 0 x 2^2 + 0 x 2^1 + 1 x 2^0 = 64 + 32 + 8 + 1 = 105;
⌨️算法代码
#include <iostream>
using namespace std;
double power(double x, int n) {
double val = 1.0;
while (n--)
val *= x;
return val;
}
int main() { // 功能:二进制转十进制
int value = 0;
cout << "Enter an 8 bit binary number: "; // 输入8位二进制数,如01101001
for (int i = 7; i >= 0; i--) {
char ch;
cin >> ch;
if (ch == '1') // 如果位数是1
value += static_cast<int>(pow(2, i)); // 乘以权重,即2的i次方,其结果转化位Int,并累加至value
}
cout << "Decimal value is " << value << endl;
return 0;
}
🐋3.3 数学公式1:用反切函数表示pi
🧩题目
📇算法思路
- arctan(x)重复出现,在本题按照泰勒展开式,可以单独写为被调用的函数;
- 在main()函数中调用arctan(x),实现计算公式;
⌨️算法代码
#include <iostream>
using namespace std;
// arctan x = x - x^3/3 + x^5/5 - x^7/7 + ...
double arctan(double x) {
double sqr = x * x; // 幂次公差项
double e = x; // 幂次初始项
double r = 0; // 计算结果
int i = 1; // 常数项
while (e / i > 1e-15) { // 精度要求:e / i > 10^-15时,结束循环
double f = e / i; // x / 1,x^3 / 3,x^5 / 5…
r = (i % 4 == 1) ? r + f : r - f; // 根据公式,x、x^5、x^9…项为正,x^3、x^7、x^11…为负
e = e * sqr; // x → x^3 → x^5 …
i += 2;
}
return r;
}
int main()
{
double a = 16.0 * arctan(1 / 5.0);
double b = 4.0 * arctan(1 / 239.0);
// 注意:因为整数相除结果取整,如果参数写1/5,1/239,结果都是0;
// pi = 16*arctan(1/5) - 4*arctan(1/239),运行结果:3.14159
cout << "PI = " << a - b << endl;
return 0;
}
📇备注小事
double a = 16.0 * arctan(1 / 5.0);
double b = 4.0 * arctan(1 / 239.0);
- 因为整数相除结果取整,如果参数写1/5,1/239,结果都是0(整型相除,电脑会自动舍去小数点位);
- 对于浮点数,电脑可能没办法精确的表示,因此判断相等的方式与整数有所区别,可能不会使用“ == ”,而是两数相减,低于1个非常小的阈值则判定相等,相关练习题可参考:🌸;
🐋3.4 判断回文数
🧩题目
📇算法思路
- 回文的判断,可以单独写为被调用的函数;
- 在主函数中判断是否 m、m^2、m^3同时满足条件;
⌨️算法代码
#include <iostream>
using namespace std;
// 反转数字n,判断是否为回文
bool symm(unsigned n) {
unsigned i = n;
unsigned m = 0;
while (i > 0) {
m = m * 10 + i % 10; // 将i现在的个位数 乘以 权值,加到m(也可以理解为,将i的最低位 添加到 m的最高位)
i /= 10; // 去掉i现在的最低位
}
return m == n;
}
int main()
{
for (unsigned m = 11; m < 1000; m++)
if (symm(m) && symm(m * m) && symm(m * m * m)) { // 如果m,m^2,m^3均为回文
cout << "m = " << m;
cout << " m * m = " << m * m;
cout << " m * m * m = " << m * m * m << endl;
}
return 0;
}
🐋3.5 数学公式2:分段函数
🧩题目
📇算法思路
- sin(x)重复出现,在本题按照泰勒展开式,可以单独写为被调用的函数;
- 在main()函数中调用sin(x),使用if、else语句实现分段函数;
⌨️算法代码
#include <iostream>
#include <cmath> // 对标准库中数学函数的说明
using namespace std;
const double TINY_VALUE = 1e-10; // 计算精度为10^-10
double tsin(double x) { // sin x = x/(1!) - x^3/(3!) + x^5/(5!) …
double g = 0; // 计算结果
double t = x; // x 起始项
int n = 1; // 常数 起始项
do {
g += t;
n++;
t = -t * x * x / (2 * n - 1) / (2 * n - 2); // 计算每一个展开项
} while (fabs(t) >= TINY_VALUE); // t的绝对值 > 精度时,继续循环
return g;
}
int main()
{
double k, r, s;
cout << "r = ";
cin >> r;
cout << "s = ";
cin >> s;
if (r * r <= s * s)
k = sqrt(tsin(r) * tsin(r) + tsin(s) * tsin(s));
else
k = tsin(r * s) / 2;
cout << k << endl;
return 0;
}
🐋3.6 扔骰子
🧩题目
📇算法思路
- 难点1:产生随机数,这个可以用C++自带的srand()产生;
- 难点2:游戏规则判定输赢,使用条件判断switch + 枚举类型enum解决;
⌨️算法代码
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
// 枚举游戏状态:胜利、失败、继续游戏
enum GameStatus { WIN, LOSE, PLAYING };
// 投掷一个六面骰子两次
int rollDice() {
int die1 = 1 + rand() % 6;
int die2 = 1 + rand() % 6;
int sum = die1 + die2;
cout << "player rolled " << die1 << " + " << die2 << " = " << sum << endl;
return sum;
}
int main()
{
int sum, mypoint;
GameStatus status;
unsigned seed;
cout << "Please enter an unsigned integer for seed:";
cin >> seed; // 输入随机数种子
srand(seed); // 将种子传递给rand()
sum = rollDice(); // 第一轮投骰子,计算和数
switch (sum) {
case 7:
case 11:
status = WIN; // 如果和数为7或11则为胜,状态为WIN
break;
case 2:
case 3:
case 12:
status = LOSE; // 如果和数为2、3或12则为负,状态为LOSE
break;
default: // 其它情况,尚无结果,状态为PLAYING,记下点数
status = PLAYING;
mypoint = sum; // 求和,输出,记录为接下来胜利的点数mypoint
cout << "point is " << mypoint << endl;
break;
}
while (status == PLAYING) { // 只要状态为PLAYING,继续游戏
cout << "Rolling the dice again..." << endl;
sum = rollDice(); // 每次投掷两次骰子
cout << "The sum is " << sum << endl;
if (sum == mypoint) // 某轮的和数等于点数mypoint则取胜
status = WIN;
else if (sum == 7) // 出现和数为7则为负
status = LOSE;
}
// 当状态不为PLAYING时循环结束,输出游戏结果
if (status == WIN)
cout << "Player wins!" << endl;
else
cout << "Player loses." << endl;
return 0;
}
📇知识扩展
rand()与 srand()
- rand()可以产生随机数,但是rand()产生的是伪随机数,就是扔1次以后是这个序列,再扔1次以后还是这个序列;
- 为了避免总是用相同的序列产生随机值,通常的方法,我们会给随机数加1个种子,不同的种子会产生不同的随机数序列,初始时使用户输入,即为srand();还有一种随机的方法,可以使用当前时间使用当前时间(
time(NULL)
)作为种子产生随机值:#include <stdlib.h> #include <time.h> int main() { srand(time(NULL)); // 使用当前时间作为种子 // ... 生成随机数 return 0; }
🔚结语
博文到此结束,写得模糊或者有误之处,期待小伙伴留言讨论与批评,督促博主优化内容{例如有错误、难理解、不简洁、缺功能}等,博主会顶锅前来修改~~😶🌫️😶🌫️
我是梅头脑,本片博文若有帮助,欢迎小伙伴动动可爱的小手默默给个赞支持一下,感谢点赞小伙伴对于博主的支持~~🌟🌟
同系列的博文:🌸数据结构_梅头脑_的博客-CSDN博客
同博主的博文:🌸随笔03 笔记整理-CSDN博客