文章目录
💯前言
- 在本次学习中,我们共同分析了一道关于功效率绘占比例比较的题目,该题目根据输入数据,判断两种治疗方法的效果是否有所改善,比如是否“better”,“worse”或“same”。我们分别分析了老师的代码和我们之前的解法,并将对两者进行了对比,提出了有效的优化方式,还进行了一些知识扩展,以加强学习效果。
下面将通过清晰的结构将上述内容统一积累为一篇详细的分析文章,便于读者阅读和学习。
C++ 参考手册
💯题目描述
题目要求如下:
- 输入包含治疗方法的功效率
s1
和s2
; - 比较这两次功效率的改善幅度:
- 如果改善幅度超过 5%(即大于 0.05),则输出
better
。 - 如果退步幅度超过 5%(即小于 -0.05),则输出
worse
。 - 否则,输出
same
。
- 如果改善幅度超过 5%(即大于 0.05),则输出
输入格式
- 第一行为测试组的数量(正整数
n
)。 - 后续每行包含两个正整数
s1
和s2
,分别表示治疗方法的前后功效率。
输出格式
- 对每一组输入,根据判断解析输出
better
,worse
,或same
。
💯老师的做法分析
下面是老师的代码:
#include <iostream>
using namespace std;
int n;
float x, y;
int a, b;
int main() {
cin >> n;
cin >> a >> b;
x = b * 1.0 / a;
for (int i = 0; i < n - 1; i++) {
cin >> a >> b;
y = b * 1.0 / a;
if (y - x > 0.05)
cout << "better" << endl;
else if (x - y > 0.05)
cout << "worse" << endl;
else
cout << "same" << endl;
}
return 0;
}
分析
代码流程分析
在代码的上半部,创建了一些基础变量:
int n
:表示测试组数。float x, y
:分别用于记录基准比例和当前比例。int a, b
:用于输入每一组数据。
初始化:
- 第一个
cin
进行数组的输入:n
。 - 通过第一次输入取得
a
和b
,并计算基准比例:x = b * 1.0 / a;
,这是后续判断的基准。
- 第一个
循环处理:
- 通过一个
for
循环,进行后续数据测试的比例计算和判断:for (int i = 0; i < n - 1; i++) { cin >> a >> b; y = b * 1.0 / a; }
- 比较当前比例
y
与基准比例x
的差值:- 如果
y - x > 0.05
,输出better
; - 如果
x - y > 0.05
,输出worse
; - 否则,输出
same
。
- 如果
- 通过一个
返回值:
- 最后通过
return 0;
,程序正常退出。
- 最后通过
老师代码的优点
- 清晰的初始化逻辑:将第一次输入单独处理,避免在循环中进行特殊判断,代码逻辑更清晰。
- 变量命名规范:变量
x
和y
清楚地表示了基准比例和当前比例,便于理解。 - 结构简单直观:代码结构紧凑,逻辑分明,适合快速实现和阅读。
老师代码的潜在改进点
浮点数精度问题:
- 浮点数比较时,直接使用
y - x > 0.05
或x - y > 0.05
可能存在精度误差。 - 可以使用
fabs(y - x)
,确保绝对值比较时的鲁棒性。
- 浮点数比较时,直接使用
循环次数的控制:
- 当前循环次数为
n - 1
,因为第一组数据在循环外处理。但如果数据规模更大,这种处理方式可能会让读者误解。
- 当前循环次数为
代码扩展性:
- 如果未来需要对比例判断的逻辑进行扩展,例如添加新的规则,当前代码的紧凑结构可能不易扩展。
💯我们的解法分析
我们的代码实现如下:
#include <iostream>
using namespace std;
int main()
{
int n = 0;
double x = 0, y = 0;
cin >> n;
for(int i = 1; i <= n; i++)
{
double s1 = 0, s2 = 0;
cin >> s1 >> s2;
if(i == 1)
x = s2 * 1.0 / s1;
else
{
y = s2 * 1.0 / s1;
if((y - x) > 0.05)
cout << "better" << endl;
else if((x - y) > 0.05)
cout << "worse" << endl;
else
cout << "same" << endl;
}
}
return 0;
}
分析
代码流程分析
变量初始化:
- 使用
double x = 0, y = 0;
初始化比例变量。 - 变量作用域被限制在循环内,更加局部化,避免了不必要的全局变量。
- 使用
输入处理:
- 第一次循环时,计算基准比例
x
。 - 从第二次循环开始,计算当前比例
y
并进行比较。
- 第一次循环时,计算基准比例
比较逻辑:
- 通过
if-else
判断比例差值:- 如果
y - x > 0.05
,输出better
; - 如果
x - y > 0.05
,输出worse
; - 否则,输出
same
。
- 如果
- 通过
我们代码的优点
循环范围一致:
- 循环从
i = 1
开始,到i <= n
,统一了处理逻辑。 - 所有输入均在循环中完成,逻辑更集中。
- 循环从
使用浮点数绝对值比较:
- 如果需要,可以扩展为:
避免浮点数精度问题。if (fabs(y - x) > 0.05)
- 如果需要,可以扩展为:
局部变量的使用:
- 将比例计算变量限制在循环内部,代码更简洁,减少了全局变量的使用。
我们代码的潜在改进点
- 代码逻辑复杂度稍高:
- 在循环中判断
i == 1
是特例处理,增加了循环的复杂性。 - 如果需要扩展,可能需要进一步调整代码结构。
- 在循环中判断
💯两种解法对比与优化建议
对比
对比项 | 老师代码 | 我们的代码 |
---|---|---|
初始化逻辑 | 第一次输入在循环外,逻辑更清晰 | 初始化在循环内,逻辑稍复杂 |
变量使用 | 全局变量 x, y, a, b 明确但冗余 |
局部变量更简洁,作用域更小 |
循环范围 | for (int i = 0; i < n - 1; i++) |
for (int i = 1; i <= n; i++) |
浮点数比较 | 直接比较浮点数,有潜在精度问题 | 可扩展为绝对值比较,精度更高 |
优化建议
浮点数精度处理:
- 使用
fabs(y - x)
确保比较的精度。
- 使用
循环逻辑优化:
- 可以统一第一次数据的处理方式,将初始化逻辑集中到循环内。
扩展性增强:
- 可以通过函数封装比例计算和判断逻辑,提高代码的可读性和复用性。
💯完整优化代码
结合两种方法的优点,经过优化后得到如下代码:
#include <iostream>
#include <cmath>
using namespace std;
void compareEfficiency(double baseRatio, double currentRatio) {
if (currentRatio - baseRatio > 0.05)
cout << "better" << endl;
else if (baseRatio - currentRatio > 0.05)
cout << "worse" << endl;
else
cout << "same" << endl;
}
int main() {
int n;
cin >> n;
double baseRatio = 0.0;
for (int i = 0; i < n; i++) {
int s1, s2;
cin >> s1 >> s2;
double currentRatio = s2 * 1.0 / s1;
if (i == 0)
baseRatio = currentRatio;
else
compareEfficiency(baseRatio, currentRatio);
}
return 0;
}
💯总结
在这篇文章中,我们分析了老师的代码和我们的解法,通过对比发现了各自的优缺点,并结合两者的优势给出了优化后的最终代码。浮点数精度处理、代码结构优化、函数封装是改进的重点方向。这种方法不仅提高了代码的可读性,也为后续扩展打下了良好的基础。希望这篇文章能够帮助读者更好地理解和掌握 C++ 的编程技巧!