// 5_a2.cpp -- 体验Haffman树的结构
/**
* -> 题目要求:
* 1. 编写一个将百分制转换为五分制的算法(使用if-else语句),要求平均比较次数尽可能少。
* 假设学生成绩分布如下:
* 等级 A B C D E
* 分数 90~100 80~89 70~79 60~69 0~59
* 百分比 0.18 0.23 0.31 0.15 0.13
* 2. 此题的源程序保存为 5_a2.cpp。
**/
/**
* 原题思路:将比率pi看成是n个叶子的权,比较次数ci看成叶子的路径长度,则就是最优二叉树的构造问题。
* 找两个相邻的、权值的和较小的两个根。
* 不能简单地找两个权最小的根合并,还要求它们空间“相邻”,在分类上非此即彼。
* 小分析: 现在,这里很明显的是D和E的比率加起来的值是最低的,0.15+0.13 = 0.28,所以,可以将它放在最底层的子树;
* 接下来CDE:0.28+0.31 = 0.59, AB:0.18+0.23 = 0.41,BC:0.23+0.31 =0.54. AB先合并最佳。
* 剩下的只有AB=0.41与DE=0.28与C=0.31了.C再与DE结合成为一棵子树CDE:0.28+0.31=0.59.
* 现最后剩下的是AB = 0.41, CDE = 0.59为根,C与B的边缘条件为根,CDE为左儿子,AB为右儿子。
**/
#include <iostream>
#include <conio.h>
using std::cin;
using std::cout;
using std::endl;
char HaffmanTreeSimulate(const double & score)
{
if (score >= 80)
{
if (score > 100)
{
cout << "\n-> 注意:输入错误。\n";
}
else if (score >= 90)
{
return 'A';
}
else
{
return 'B';
}
}
else if ( score >= 70 )
{
return 'C';
}
else if ( score >= 60 )
{
return 'D';
}
else if ( score >= 0 )
{
return 'E';
}
else
{
cout << "\n-> 注意:输入错误。\n";
}
return 'W';
}
int main() // main流程: 输入 -> 显示 -> 输出判断结果 -> 循环或退出
{
char a; // 用于控制整个程序循环的字符变量
do
{
cout << "-> 开始体验Haffman树的结构:\n";
cout << "1. 请输入单个学生的分数:";
double score;
cin >> score;
while(!cin)
{
cin.sync();
cin.clear();
cout << "\n输入错误,请重新输入!";
cin >> score;
}
char fscore(HaffmanTreeSimulate(score) );
if (fscore != 'W')
{
cout << "2. 该学生的分数为:" << fscore << endl;
}
cout << "3. 请选择是否继续输入测试,如需退出,请按字符q,否则请按任意键继续...\n\n";
a = _getch();
}while(a != 'q');
return 0;
}