[College] 《C++程序设计》P66 例2.4 题目分析

例2.4

题目描述

编程计算个人所得税。个人所得税率表如下:月收入1000元起征,超过起征点500元以内部分税率5%,超过500元到2,000元部分税率10%,超过2,000元到5,000元部分税率15%,超过5,000元到20,000元部分税率20%,超过20,000元到40,000元部分税率25%,超过40,000元到60,000元部分税率30%,超过60,000元到80,000元部分税率35%,超过80,000元到100,000元部分税率40%,超过100,000元部分税率45%。

样例输入

66666

样例输出

16608.1

AC代码

#include<iostream>
#include<cstdlib>

using namespace std;

int main()
{
    double income,paytax=0,dis,exceed;//dis为在当前区间需单独计算税额的金额,exceed为收入超过起征点的额度;
    cout<<"请输入月收入:"<<endl;
    cin>>income;
    exceed=income-1000;
    if(exceed<=0)
    {
        cout<<"无需缴纳个人所得税。"<<endl;
        system("pause");
        return 0;
    }
    int Level=(exceed>=100000)+(exceed>=80000)+(exceed>=60000)+(exceed>=40000)+(exceed>=20000)+(exceed>=5000)+(exceed>=2000)+(exceed>=500)+(exceed>=0);
    //Level用于标记exceed所处的区间;
    switch(Level)//针对所处区间进行计算
    {
        case 9:  dis=exceed-100000; paytax+=(dis*0.45); exceed-=dis;//计算当前区间的金额dis;paytax累加;更新exceed;
        case 8:  dis=exceed-80000;  paytax+=(dis*0.40); exceed-=dis;
        case 7:  dis=exceed-60000;  paytax+=(dis*0.35); exceed-=dis;
        case 6:  dis=exceed-40000;  paytax+=(dis*0.30); exceed-=dis;
        case 5:  dis=exceed-20000;  paytax+=(dis*0.25); exceed-=dis;
        case 4:  dis=exceed-5000;   paytax+=(dis*0.20); exceed-=dis;
        case 3:  dis=exceed-2000;   paytax+=(dis*0.15); exceed-=dis;
        case 2:  dis=exceed-500;    paytax+=(dis*0.10); exceed-=dis;
        case 1:  dis=exceed;        paytax+=(dis*0.05);
    }
    cout<<"应缴纳的个人所得税为:"<<paytax<<" 元。"<<endl;
    system("pause");
    return 0;
}

<代码分析>

1、在使用switch前对数据的处理:由于switch只能对范围较小的数据进行分支判断,因此,当数据范围较大时,我们最好在之前对数据进行恰当的处理。例如在本例中,对80000-100000这个范围进行switch分支操作,即使整除500,也依然需要20000/500=40个case才能覆盖这个区间。这时,我们不妨对数据进行离散化处理,将分散的、范围较大的数据简化为相对密集的、范围较小的数据,这样就便于后面的switch操作:

int Level=(exceed>=100000)+(exceed>=80000)+(exceed>=60000)+(exceed>=40000)+(exceed>=20000)+(exceed>=5000)+(exceed>=2000)+(exceed>=500)+(exceed>=0);

程序中的这行代码可以说是整个程序的点睛之笔,赋给Level的表达式通过比较大小后的bool型返回值之和,将exceed在不同区间的状态表达了出来,相比于冗长的if串判断,显然更加优秀。

类似的,我们也可以通过对数据分段进行switch操作,甚至是switch的嵌套来完成大范围数据的switch分支处理。

2、在switch的分支结构case中,break并非是必要的。例如题目中的这种情况,我们恰好可以利用不含break的case语句实现特定的功能。

3、关于default的位置:default并不一定要放在所有case语句的最后,事实上,default可以放在我们想要的任意位置。例如,当我们需要对一个半开放区间[inf,+∞)单独设置一个分支时,不妨这样做:

switch(num)
{
    default:
    case (inf-1):
    case (inf-2):
    case (inf-3):
    ......
}

 这样,default就代表了处于[inf,∞)的所有情况~

原文地址:https://www.cnblogs.com/SinGuLaRiTy2001/p/11728309.html