這章講的是資料結構對程式的影響:
使得程式**簡潔、已讀。畢竟程式是給人看的,所以能被人看懂,才是**的首要任務。
提高效率。不僅是**的執行效率,還有**的維護效率。
習題1:稅收問題。題目中使用if-else的分支語句的缺點有兩點:
**太長,需要大概500行**左右才能完成功能,也不利於之後的**更新。
**從上到下執行,是乙個順序查詢的過程,效率太低。
問題分析:分段的稅收問題。這個問題可以有兩種方法進行處理:
遞推公式法。很容易就可以得到分段稅收的遞推公式,但是對於一次稅收結果的計算時間複雜度太高。稅收計算可能是需要進行大規模計算的,所以遞推公式法並不適應於現實情況。
陣列分階段查詢法。對於每乙個階段可以用公式表示:本階段基礎稅 + 本階段稅率 * (income - 本階段基礎收人),其實這與題目中的if-else分支方法中的做法一樣。現在需要有兩個陣列來記錄 「本階段基礎稅」 和「本階段基礎收入」,對於「本階段稅率」可以由陣列的下標計算出來。接下來的問題就對陣列的查詢,對於這個問題可以使用兩個方法:二分查詢、標示法(取餘)。**如下:
#include using namespace std;
#define minicome 2200 //最低徵稅收入
#define maxicome 102200 //階段收稅的最大收入,大於此收入的按照統一標準
#define icomespan 500 //階段稅收的跨度
#define minrate 0.14 //最低稅率
#define ratespan 0.01 //稅率的跨度
double incomearray[(maxicome - minicome) / icomespan + 1]; //階段收入陣列
double basetaxarray[(maxicome - minicome) / icomespan + 1];//階段稅陣列
//使用二分查詢計算稅
double calculatetax(double income)
else if(income >= maxicome)
//使用二分查詢,找到income所處的階段, incomearray[i] <= income < incomearray[i+1]
//二分查詢的區間[ start, end ), 左閉右開。
int start = 0;
int end = (maxicome - minicome) / icomespan;
while(!(incomearray[start] <= income && income < incomearray[start+1]))
else
} return basetaxarray[start] + (minrate + ratespan * start) * (income - incomearray[start]);
}//使用標註法
double calculatetax2(double income)
else if(income >= maxicome)
int index = (int)((income - minicome) / icomespan);//確定階段所對應的索引
return basetaxarray[index] + (minrate + ratespan * index) * (income - incomearray[index]);
}int main()
else }
cout << calculatetax(3800) << endl;
cout << calculatetax2(3800) << endl;
}
習題4:解決日期問題。給定兩個日期計算兩者之間的天數;給定乙個日期,返回是週幾;給定年和月,生成該月日曆;**如下:
#include #include #include #include using namespace std;
/*date用來表示年月日*/
struct date
bool operator< (date& newdate)
};/*
sumdaysofmonth中第i項表示第i+1月1日到1月1日的天數累加和。
這裡只是初始值,下面的for迴圈會計算累加和。
*/ unsigned int sumdaysofmonth[12] = ;
/*判斷year是否為閏年, 如果是閏年返回true*/
bool isornotleapyear(unsigned int year)
/*計算earlierdate和laterdate之間的天數*/
unsigned int daysbetweendates(date earlierdate, date laterdate)
/* daystoearlieryear:表示日期 earlierdate到 earlierdate.year年1月1日的天數
daystolateryear:表示日期 laterdate 到 laterdate.year年1月1日的天數
daysbetweenearlierandlateryear:表示 earlierdate.year年1月1日 到 laterdate.year年1月1日的天數
daysbetweendates = daystolateryear + daysbetweenearlierandlateryear - daystoearlieryear;
*/ unsigned int daysbetweendates = 0;
unsigned int daystoearlieryear = 0;
unsigned int daystolateryear = 0;
unsigned int daysbetweenearlierandlateryear = 0;
daystoearlieryear = earlierdate.month > 1 ?
sumdaysofmonth[earlierdate.month - 2] + earlierdate.day :
earlierdate.day;
if(isornotleapyear(earlierdate.year) && earlierdate.month > 2) daystoearlieryear++;
daystolateryear = laterdate.month > 1 ?
sumdaysofmonth[laterdate.month - 2] + laterdate.day :
earlierdate.day;
if(isornotleapyear(laterdate.year) && laterdate.month > 2) daystolateryear++;
unsigned int currentyear = earlierdate.year;
while(currentyear < laterdate.year)
else
currentyear++; }
daysbetweendates = daystolateryear + daysbetweenearlierandlateryear - daystoearlieryear;
return daysbetweendates; }/*
weekday:計算date是星期幾。
一般日曆都是以2023年1月1日,星期1,作為基準日期
*/unsigned int weekday(date& date)
void showmonth(unsigned int year, unsigned int month);
if(isornotleapyear(year)) daysofmonth[1]++;
unsigned int weekday = weekday(date);
cout << weekday << endl;
unsigned int day = 1;
while(day <= daysofmonth[month - 1])
for(int i = 0; i < calendarformonth.size(); i++)
cout << endl; }}
int main()
date date1(2018, 8, 8);
date date2(2020, 8, 8);
date date3(2020, 9, 12);
cout << daysbetweendates(date1, date2) << endl;
cout << weekday(date3) << endl;
showmonth(2020, 10);
return 0;
}
結果:
程式設計珠璣第三章
第三章寫的有點太簡單了,可能作者是想在後面章節裡再詳細說吧!這一章就是作者說的幾句話印象還是很深刻。程式設計師在節省空間方面無計可施時,將自己從 中解脫出來,退回起點並記者並集 中精力研究資料,常常能有奇效。資料的 表示形式是程式設計的根本。正如人月神話的作者說 只要給我你設計的表,我就對你的程式一...
程式設計珠璣第三章習題1
問題 1.本書行將出版之時,美國的個人所得稅分為5種不同的費率,其中最大的費率大約為40 以前的情況更為複雜,稅率也更高。下面所示的程式文字採用25個if語句的合理方式來計算1978年的美國聯邦所得稅。稅率分別為0.14,0.15,0.16,0.17,0.18,此後的費率增幅大於0.01.有何建議?...
程式設計珠璣之第三章習題3
問題描述 3.編寫乙個 banner 函式,該函式的輸入為大寫字母,輸出為乙個字元陣列,該陣列以圖形化的方式表示該字母。問題解析 1 如果編寫乙個通用的以26個字母為引數,輸出為該字母的圖形化表示,我目前還沒有有效的方法,不過這對單個的字母,就簡單的多,這也是目前想到的解決該問題的方法,就是在該函式...