Book notes
主旨是:don’t wirte a big program when a little one will do.
一些原则:
- 重构重复的代码到数组。
- 封装复杂的结构。
- 尽可能使用高级工具。
- 让数据来构建程序。
Problems
1
- 建立一张税收表格,包括 1.这个一行数据范围的最低收入; 2.税收的基本费用; 和 3.税收比率。
- 用给定税收,二分搜索所处范围,也就是表格的哪一栏。用公式算出税收。
3
编写标语函数,输入一个大写字母,输出一个字符数组,该字符数组用字符图形方式描绘该字母
- 用一个定义的模板语言为每个字母定义标语的格式,存入一个 table 中;
- 写一个对这个自定义模板语言的解析程序,把它解析成打印标语;
- 输入一个单词,直接读取 table 相应的模板格式,用解析程序解析。
如字母 I 如下,可以把它编码成:
3 lines 9 X 6 lines 3 blank 3 X 3 blank 3 lines 9 X
或更简化:
3 9 X 6 3 b 3 x 3 b 3 9 x
x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
4
#include <cstdio> #include <vector> using std::vector; struct Date { Date(int year_in, int month_in, int day_in) { year = year_in; month = month_in; day = day_in; } int year; int month; int day; }; const int kMonthDays[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int KDaysOfWeek = 7; enum YearDays { kNormYearDays = 365, kLeapYearDays = 366, }; bool IsLeapYear(const int &year) { if ((year % 400 == 0) || (((year % 4) == 0) && (year % 100) != 0)) { return true; } else { return false; } } int MonthDaysOfYear(int year, int month) { int days = kMonthDays[month]; if (month == 2 && IsLeapYear(year)) { days++; } return days; } int DaysOfYear(const Date &date) { int days = 0; days += date.day; for (int i = 1; i < date.month; ++i) { days += MonthDaysOfYear(date.year, i); } return days; } int DaysBetween(const Date &date_pre, const Date &date_next) { int days = 0; for (int year_ = date_pre.year; year_ < date_next.year; ++year_) { days += (IsLeapYear(year_) ? kLeapYearDays : kNormYearDays); } days += DaysOfYear(date_next); days -= DaysOfYear(date_pre); return days; } void PrintCalendar(const vector<vector<int> > &calendar) { printf("Sun Mon Tue Wed Thu Fri Sat\n"); int i; for (i = 0; i < KDaysOfWeek - calendar[0].size(); ++i) { printf(" "); } for (i = 0; i < calendar.size(); ++i) { for (int j = 0; j < calendar[i].size(); ++j) { printf("%-4d", calendar[i][j]); } printf("\n"); } } int DayOfWeek(const Date &date) { const Date kFirstDate(1900, 1, 1); // Mon return (DaysBetween(kFirstDate, date) % 7 + 1); } void CalendarOfMonth(int year, int month, vector<vector<int> > *calendar) { Date first_of_month(year, month, 1); int day_of_week = DayOfWeek(first_of_month); vector<int> temp; for (int i = 0; i < MonthDaysOfYear(year, month); ++i) { temp.push_back(i); if ((day_of_week + i) % KDaysOfWeek == 6) { calendar->push_back(temp); temp.clear(); } } printf("Year:%d Month:%d\n", year, month); PrintCalendar(*calendar); }
5
查找后缀连字符的连接。
const char *kHyphWords[] = {"et-ic", "al-is-tic", "s-tic", "p-tic", "-lyt-ic", "ot-ic", "an-tic", "n-tic", "c-tic", "at-ic", "h-nic", "n-ic", "m-ic", "l-lic", "b-lic", "-clic", "l-ic", "h-ic", "f-ic", "d-ic", "-bic", "a-ic", "-mac", "i-ac"}; static vector<string> *reverse_hyphs = NULL; void ReverseHypenation(const char *word, char *reverse_word) { const char kHypen = '-'; int len = strlen(word) - 1; int i, j; for (i = 0, j = 0; i <= len; ++i) { if (word[len - i] == kHypen) continue; reverse_word[j++] = word[len - i]; } reverse_word[j] = '\0'; } void RerverseWord(const string &word, string *reverse_word) { *reverse_word = word; reverse(reverse_word->begin(), reverse_word->end()); } void PreProcessHyphenation() { if (reverse_hyphs != NULL) { return; } else { reverse_hyphs = new vector<string>(); int n = sizeof(kHyphWords) / sizeof(kHyphWords[0]); for (int i = 0; i < n; ++i) { const int kMaxLen = 10; char reverse_word[kMaxLen]; ReverseHypenation(kHyphWords[i], reverse_word); reverse_hyphs->push_back(string(reverse_word)); } } } bool IsBeginWith(const string &word, const string &begin_letter) { if (word.size() < begin_letter.size()) { return false; } for (int i = 0; i < begin_letter.size(); ++i) { if (begin_letter[i] != word[i]) { return false; } } return true; } string FindHyphenation(const string &word) { PreProcessHyphenation(); string reverse_word; RerverseWord(word, &reverse_word); for (int i = 0; i < reverse_hyphs->size(); ++i) { if (IsBeginWith(reverse_word, reverse_hyphs->at(i))) { return string(kHyphWords[i]); } } return ""; }