欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

编程珠玑 -- 数据结构?

程序员文章站 2022-06-12 18:38:25
...

又开始看《编程珠玑》,发现之前看的也许不是很认真吧,再看一遍的时候竟没有什么似曾相识的感觉。于是便开始做后面的习题了,也许这样能让我对这一章的内容印象更深刻些。

第三章介绍了几个案例,说明了数据的组织是如何影响程序的结构的,说到底,就是要设计好的数据结构,以减少编程的量。这一章的内容相对简单,我做了后面两道题: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成员在对象的定义体内声明,但必须在定义体外定义。一开始我在对象定义体内就给它赋初值,结果总是编译出错。