又开始看《编程珠玑》,发现之前看的也许不是很认真吧,再看一遍的时候竟没有什么似曾相识的感觉。于是便开始做后面的习题了,也许这样能让我对这一章的内容印象更深刻些。
第三章介绍了几个案例,说明了数据的组织是如何影响程序的结构的,说到底,就是要设计好的数据结构,以减少编程的量。这一章的内容相对简单,我做了后面两道题:3.7的第1题和第4题,贴在这里了:
第一题:
double getTax( int income ){
//用这两个数组来代替程序员的25条if语句
int base[25] = { 0, 2200, 2700, 3200, 3700, ..., 102200};
double rate[25] = { 0, 0.14, 0.15, 0.16,0.17, ..., 0.7} ;
int init = 24;
while( income<base[init] && init>=0 )
init --;
double tax = 0;
tax += (income-base[init])*rate[init];
while( init>0 ){
tax += (base[init]-base[init-1])*rate[init-1];
init --;
}
return tax;
}
第四题:
#include<iostream>
using namespace std;
class MyDate{
public:
int day;
int month;
int year;
MyDate( int yy, int mm, int dd ){
day = dd;
month = mm;
year = yy;
if( !check() ){
cerr<<"invalid date!"<<endl;
}
}
//检查日期是否合理
bool check(){
if( year<0 || month<=0 || month>12 || day<1 )
return false;
if( month == 2 && isLeap(year) )
return day<=29;
else
return day <= daysOfMonths[month];
}
//计算两个日期之间的天数时,首先找出较小的那个,before( another )返回this指向的日期是否比another早
bool before( MyDate another ){
return (another.year>year) || (another.year==year && another.month>month )
|| (another.year==year&&another.month==month&&another.day>day) ;
}
//特定年份是否为闰年
bool isLeap( int year ){
return ( year%400==0 || (year%100!=0 && year%4==0 ) );
}
//计算该日期距离年份yy的第一天有多少天
int daysFromYear( int yy ){
int days = 0;
if( year < yy )
return -1;
while( year>yy ){
days += (isLeap(yy)?366:365);
yy ++ ;
}
int mm = 1;
while( mm<month ){
days += daysOfMonths[mm];
mm ++;
}
if( month>2 && isLeap(year) )
days ++;
days += day;
return days;
}
//这里就是计算this的日期与another的日期之间有多少天,
//它们共同以最早的那个年份为基础,计算距离那天过了多少天
//然后算出差距即是两个日期之间的差距
int getDaysCount( MyDate another ){
if( before( another ) )
return (another.daysFromYear(year) - daysFromYear(year));
else
return (daysFromYear(another.year) - another.daysFromYear(another.year));
}
//计算this日期是星期几
int getWeekDay(){
int count = getDaysCount( ReferDay );
if( before( ReferDay ) )
return ((RefWeekDay + 7 - count%7 )%7 );
else
return (RefWeekDay+count%7)%7;
}
//打印出this日期所在月份的日历
void printMonth(){
cout<<"\n\n";
cout<<"Month "<<month<<" Year "<<year<<endl;
int dayOfMonth = daysOfMonths[month];
if( month == 2 && isLeap(year) )
dayOfMonth++;
MyDate firstDay = MyDate( year, month, 1 );
int firstWeekDay = firstDay.getWeekDay();
int weekDay = firstWeekDay;
for( int i=0; i<weekDay; i++ )
cout<<"\t_______";
for( int i=1; i<10; i++ ){
cout<<"\t0"<<i<<"{"<<Str_Date[weekDay]<<"}";
if( weekDay == 6 )
cout<<"\n";
weekDay = (weekDay+1)%7;
}
for( int i=10; i<=dayOfMonth; i++ ){
cout<<"\t"<<i<<"{"<<Str_Date[weekDay]<<"}";
if( weekDay == 6 )
cout<<"\n";
weekDay = (weekDay+1)%7;
}
}
private:
static const int MONTHS_OF_YEAR = 12;
static const int DAYS_OF_WEEK = 7;
static int daysOfMonths[MONTHS_OF_YEAR+1];
static string Str_Date[DAYS_OF_WEEK];
static MyDate ReferDay;
static int RefWeekDay;
};
int MyDate::daysOfMonths[MyDate::MONTHS_OF_YEAR+1] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
string MyDate::Str_Date[MyDate::DAYS_OF_WEEK] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
MyDate MyDate::ReferDay = MyDate( 2011, 12, 21 );
int MyDate::RefWeekDay = 3;
算法上来说自然是没有什么难度的,不过就是尽量写得简洁吧。
很惭愧的,看了《C++ primer》之后就又开始用java编程了,结果又回来写C++的时候就又把它们的语法混在一起了,通过第四题的编程,记住了下面两点:
(1)this是一个指针,所以如果要在函数体内显式使用this的话,用的是->操作符,而不是.操作符。我把它跟java混在一起了,然后用this.year,一直编译出错。
(2)对象的static成员在对象的定义体内声明,但必须在定义体外定义。一开始我在对象定义体内就给它赋初值,结果总是编译出错。