Programming Abstraction in C++习题作业集

Standford University

C++抽象编程 斯坦福大学中级编程课

http://web.stanford.edu/class/cs106b/


第八章 迭代策略 (Recursive Strategies)

Psychologically, however, the important thing is to avoid asking that question altogether.

例题,移动环,每次移动一个,大的不能在小的上面。

#include 

using namespace std;

void moveTower(int n, char start, char finish, char tmp);
void moveSingleDisk(char start, char finish);

int main() {
    int n = 5;
    moveTower(n, 'A', 'B', 'C');
    return 0;
}

void moveTower(int n, char start, char finish, char tmp) {
    if (n == 1) {
        moveSingleDisk(start, finish);
    } else {
        moveTower(n - 1, start, tmp, finish);
        moveSingleDisk(start, finish);
        moveTower(n - 1, tmp, finish, start);
    }
}

void moveSingleDisk(char start, char finish) {
    cout << start << " -> " << finish << endl;
}



1. Overivew of C++

C++概述

1.1 Your first C++ program

讲述了hello world的输出,照着书上的代码敲。

1.2 The history of C++

主要讲面向对象的发展历史,C++主要在C的基础上发展而来。

source file -> object file (compiler) -> executable file (linker)

1.3 The structure of C++ program

program comments

Library inclusions

Function prototype

Main program

Function comment

Function definition

1.4 Variables

局部变量和全局变量

1.5 数据类型

1.6 表达式

1.7 语句

总结

这部分主要讲述C++基础,内容从各小节的标题可以看出来,以后不再复习此类基础。

复习题
1. source file
2. /* */ //
3. <> system library, "" user library
4. const double CENTIMETERS_PER_INCH = 2.54;
5. main, return
6. next line
7. name 名字,type 类型,value,数值,scope,作用域
8. a b c e f h i j k l
9. field operation
10. short <= int <= long
11. 美国字符数值表
12. true false
13. #include double x;
14. cout << "i " << + i << " d " << d
    << " c " << c << " s " << s;
15. int 5, int 3, double 3.8
    double 18, int 4, int 2
16. 正负值,减法操作
17. 去掉小数部分
18. type()
19. 4, 2, 42, 42
20. =
21. ++x先加1再使用,x++先使用再加1
22. 字母缩减
23. if(statement) {}
    switch(statement) { case: break; default: ;}
    while(statement) {}
    for(init, test, s) {}
24. switch只能是整形变量,每个case后有个break防止进入下一个case,
    末尾可以有default,在没有任何case匹配的情况下执行。
25. 特殊的记号
26. for (int i = 0; i <= 100; i++)
    for (int i = 0; i < 100; i+=7)
    for (int i = 100; i >= 0; i-=2)


/* Chapter 1 exercises */

#include 
#include "console.h"
#include 
using namespace std;

int digitReverse(int n);
bool isPrime(int n);
void hailstoneSequence(int n);

int main() {
    /* exercise 1
    // reads in a temperature in degrees Celsius and
    // displays the corresponding temperature in degrees Fahrenheit.
    cout << "Enter a temperature in degrees Celsius: ";
    double celsius = 0;
    cin >> celsius;
    double fahrenheit = celsius * 9.0 / 5 + 32;
    cout << "Corresponding temperature in degrees Fahrenheit: " << fahrenheit << endl;
    return 0;
    */

    /* exercise 2
    // convert a distance in meters to the corresponding English distance in feet and inches.
    // 1 inch = 0.0254 meters
    // 1 foot = 12 inch
    cout << "Enter a distance in meters: ";
    double meters = 0;
    cin >> meters;

    int inches = int (meters / 0.0254);
    int feet = inches / 12;
    inches = inches % 12;

    cout << "Distance in feet and inches: " << feet << " feet, " << inches << " inches" << endl;
    return 0;
    */

    /* exercise 3
    // compute the sum of the numbers between 1 and 100.
    int sum = 0;
    for (int i = 1; i <= 100; i++) {
        sum += i;
    }
    cout << "the sum of the numbers between 1 and 100: " << sum << endl;
    return 0;
    */

    /* exercise 4
    // read in a positive integer N and then calculates and displays the
    // sum of the first N odd integers.
    cout << "Enter a positive integer: ";
    int n, sum = 0;
    cin >> n;
    for (int i = 0; i < n; i++) {
        sum += 2 * i + 1;
    }
    cout << "the sum of the first N odd integers: " << sum << endl;
    return 0;
    */

    /* exercise 5 & 6
    cout << "This program finds the largeset integer in a list." << endl;
    cout << "Enter 0 to signal the end of the list." << endl;
    int largest = 0;
    int larger = 0;
    int sentinel = 0;
    int number;
    while (true) {
        cout << "? ";
        cin >> number;
        if (number > largest) {
            larger = largest;
            largest = number;
        }
        if (number == sentinel) break;
    }
    cout << "The largest value was " << largest << ".\n";
    cout << "The second largest value was " << larger << ".\n";
    return 0;
    */

    /* exercise 7
    const int SENTINEL = -1;
    cout << "This program adds a list of numbers." << endl;
    cout << "Use " << SENTINEL << " to signal the end." << endl;

    int total = 0;
    int count = 0;
    while (true) {
        int value;
        cout << " ? ";
        cin >> value;
        if (value == SENTINEL) break;
        count++;
        total += value;
    }
    cout << "The average grade of student is: " << total / count << endl;
    return 0;
    */

    /* exercise 8
    cout << "This program reverses the digits in an integer." << endl;
    cout << "Enter a positive integer: ";
    int number;
    cin >> number;
    cout << "The reversed integer is " << digitReverse(number) << endl;
    return 0;
    */

    /* exercise 9
    cout << "This program factors a number." << endl;
    cout << "Enter number to be factored: ";
    int number;
    cin >> number;
    int max = number;
    for (int i = 2; i <= max; i++) {
        while (number % i == 0) {
            cout << i;
            number = number / i;
            if (number != 1) cout << " * ";
        }
    }
    return 0;
    */

    /* exercise 10
    cout << "Enter a number: ";
    int number;
    cin >> number;

    hailstoneSequence(15);
    return 0;
    */

    /*
    double sum  =0;
    bool flag = true;

    for ( int i = 0; i < 10000; i++) {
        if (flag) {
            sum += 1.0/(2*i + 1);
            flag = false;
        } else {
            sum -= 1.0/(2*i + 1);
            flag = true;
        }
    }

    cout << "PI = " << sum * 4 << endl;
    */
    
    double sum = 0;

    for (int i = 0; i < 10000; i++) {
        sum += (1.0/10000) * sqrt(1.0 - 1.0 / 10000 * 1.0 / 10000 * i * i);
    }
    cout << "PI = " << sum * 4 << endl;
    return 0;

}

bool isPrime(int n) {
    for (int i = 2; i < n; i++) {
        if (n % i == 0) return false;
    }
    return true;
}

int digitReverse(int n) {
    int reverse = 0;
    while (n > 0) {
        reverse *= 10;
        reverse += n % 10;
        n /= 10;
    }
    return reverse;
}

bool isOdd(int n) {
    if (n % 2 == 1) return true;
    return false;
}


void hailstoneSequence(int n) {
    while (n != 1) {
        if (isOdd(n)) {
            cout << n << " is odd, so I multiply by 3 and add 1 to get ";
            n = n * 3 + 1;
            cout << n << endl;
        } else {
            cout << n << " is even, so I divide it by 2 to get ";
            n = n / 2;
            cout << n << endl;
        }
    }

}

/*
 * output
 *
 * exercise 1
 * Enter a temperature in degrees Celsius: 23
 * Corresponding temperature in degrees Fahrenheit: 73.4
 *
 * exercise 2
 * Enter a distance in meters: 52
 * Distance in feet and inches: 170 feet, 7 inches
 *
 * exercise 3
 * the sum of the numbers between 1 and 100: 5050
 *
 * exercise 4
 * Enter a positive integer: 4
 * the sum of the first N odd integers: 16
 *
 * exercise 5
 * This program finds the largeset integer in a list.
 * Enter 0 to signal the end of the list.
 * ? 17
 * ? 42
 * ? 11
 * ? 19
 * ? 35
 * ? 0
 * The largest value was 42.
 *
 * exercise 6
 * This program finds the largeset integer in a list.
 * Enter 0 to signal the end of the list.
 * ? 223
 * ? 251
 * ? 317
 * ? 636
 * ? 766
 * ? 607
 * ? 607
 * ? 0
 * The largest value was 766.
 * The second largest value was 636.
 *
 * exercise 7
 * This program adds a list of numbers.
 * Use -1 to signal the end.
 * ? 1
 * ? 2
 * ? 3
 * ? -1
 * The average grade of student is: 2
 *
 * exercise 8
 * This program reverses the digits in an integer.
 * Enter a positive integer: 123456789
 * The reversed integer is 987654321
 *
 * exercise 9
 * This program factors a number.
 * Enter number to be factored: 60
 * 2 * 2 * 3 * 5
 *
 * exercise 10
 * Enter a number: 15
 * 15 is odd, so I multiply by 3 and add 1 to get 46
 * 46 is even, so I divide it by 2 to get 23
 * 23 is odd, so I multiply by 3 and add 1 to get 70
 * 70 is even, so I divide it by 2 to get 35
 * 35 is odd, so I multiply by 3 and add 1 to get 106
 * 106 is even, so I divide it by 2 to get 53
 * 53 is odd, so I multiply by 3 and add 1 to get 160
 * 160 is even, so I divide it by 2 to get 80
 * 80 is even, so I divide it by 2 to get 40
 * 40 is even, so I divide it by 2 to get 20
 * 20 is even, so I divide it by 2 to get 10
 * 10 is even, so I divide it by 2 to get 5
 * 5 is odd, so I multiply by 3 and add 1 to get 16
 * 16 is even, so I divide it by 2 to get 8
 * 8 is even, so I divide it by 2 to get 4
 * 4 is even, so I divide it by 2 to get 2
 * 2 is even, so I divide it by 2 to get 1
 *
 * exercise 11
 * PI = 3.14149
 *
 * exercise 12
 * PI = 3.14179
 */

第二章 函数与库

2.1 The idea of a function

2.2 Libraries

2.3 Defining functions in C++

2.4 The mechanics of function calls

2.5 Reference parameters

2.6 Interfaces and implementations

2.7 Principles of interface design

2.8 Designing a random number library

2.9 Introduction to the Standard libraries

主要介绍函数与库的使用,基本原理都已经掌握。


复习题
1. 函数是执行某些操作的模块,程序是运行在机器上的实例。
2. 调用函数,函数参数,返回值。
3. fallse
4. double sqrt(double d);
5. yes
6. bool function
7. 函数名相同,参数类型或者个数不相同。
8. 声明中等于默认值。
9. false
10. 调用函数时的保存参数的堆栈。
11. 函数括号内的参数。
12. 只在本函数内可以使用。
13. 调用时不进行copy,直接使用原来的值进行操作。
14. &
15. 用户,实现,接口
16. #ifndef _mylib_h
    #define _mylib_h
    #endif
17. 声明和实现中都需要export
18. 函数调用的基础。
19. 用户不用改自己的程序。
20. 生成随机数。
21. 整形数据的最大值。
22. normalize, scale, translate, convert.
23. randomInteger(1, 100);
24. -5 ~ 5
25. no
26. true
27. 设置初始值。
28. 每次初始值不变。
29. 生成随机整形,浮点型数据,以及可以设置初始值

combinatorics.h

#ifndef COMBINATORICS_H
#define COMBINATORICS_H

int combinations(int n, int k);
int permutations(int n, int k);
#endif // COMBINATORICS_H

combinatorics.cpp

#include "combinatorics.h"
int fact(int n) {
    int result = 1;
    for (int i = 1; i <=n; i++) {
        result *= i;
    }
    return result;
}

int combinations(int n, int k)
{
    return fact(n) / (fact(k) * fact(n - k));
}

int permutations(int n, int k)
{
    int multi = 1;
    for (int i = n; i > k; i--) {
        multi *= i;
    }
    return multi;
}
#include 
#include "combinatorics.h"
using namespace std;

int main(int argc, char *argv[])
{
    cout << "Test combinatorics: " << endl;
    cout << combinations(5, 2) << endl;
    cout << permutations(5, 2) << endl;
    return 0;
}

/*
 * output
 * Test combinatorics:
 * 10
 * 60
 */


#ifndef CALENDAR_H
#define CALENDAR_H
#include 

enum Month {
    JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST,
    SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER
};

int daysInMonth(Month month, int year);
bool isLeapYear(int year);
std::string monthToString(Month month);

#endif // CALENDAR_H
#include "calendar.h"
#include 
#include 

int daysInMonth(Month month, int year)
{
    switch (month) {
    case 0:
        return 31;
    case 1:
        if (isLeapYear(year))
            return 29;
        else
            return 28;
    case 2:
        return 31;
    case 3:
        return 30;
    case 4:
        return 31;
    case 5:
        return 30;
    case 6:
        return 31;
    case 7:
        return 31;
    case 8:
        return 30;
    case 9:
        return 31;
    case 10:
        return 30;
    case 11:
        return 31;
    default:
        std::cout << "invalid month.";
        break;
    }
}

bool isLeapYear(int year)
{
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

std::string monthToString(Month month)
{
    switch (month) {
    case 0:
        return "JANUARY";
    case 1:
        return "FEBRUARY";
    case 2:
        return "MARCH";
    case 3:
        return "APRIL";
    case 4:
        return "MAY";
    case 5:
        return "JUNE";
    case 6:
        return "JULY";
    case 7:
        return "AUGUST";
    case 8:
        return "SEPTEMBER";
    case 9:
        return "OCTOBER";
    case 10:
        return "NOVEMBER";
    case 11:
        return "DECEMBER";
    default:
        std::cout << "invalid month";
        break;
    }
}
#include 
#include "calendar.h"

using namespace std;

int main(int argc, char *argv[])
{
    cout << "Enter a year: ";
    int year;
    cin >> year;
    for (int i = 0; i < 12; i++) {
        cout << monthToString(Month(i)) << "has " << daysInMonth(Month(i), year) << " days." << endl;
    }
}

/*
 * output
 * Enter a year: 2014
 * JANUARYhas 31 days.
 * FEBRUARYhas 28 days.
 * MARCHhas 31 days.
 * APRILhas 30 days.
 * MAYhas 31 days.
 * JUNEhas 30 days.
 * JULYhas 31 days.
 * AUGUSThas 31 days.
 * SEPTEMBERhas 30 days.
 * OCTOBERhas 31 days.
 * NOVEMBERhas 30 days.
 * DECEMBERhas 31 days.
 */

#include 
#include 
#include 
#include 
#include 
#include "console.h"
#include "random.h"
#include "gwindow.h"

using namespace std;

double celsiusToFahrenheit(double c);
void meterToInchAndFoot(double meter, int &foot, int &inch);
int roundToNearestInt(double x);
double windChill(double t, double v);
bool isPerfect(int number);
bool isPrime(int number);
double sqrtN(double x);
void findEaster(int year, string & month, int & day);
// int permutations(int n, int k);

/* Main program */
int main() {
    /* exercise 1
    // reads in a temperature in degrees Celsius and
    // displays the corresponding temperature in degrees Fahrenheit.
    cout << "Enter a temperature in degrees Celsius: ";
    double celsius = 0;
    cin >> celsius;
    double fahrenheit = celsiusToFahrenheit(celsius);
    cout << "Corresponding temperature in degrees Fahrenheit: " << fahrenheit << endl;
    return 0;
    */

    /*
    // convert a distance in meters to the corresponding English distance in feet and inches.
    // 1 inch = 0.0254 meters
    // 1 foot = 12 inch
    cout << "Enter a distance in meters: ";
    double meters = 0;
    cin >> meters;
    int foot, inch;
    meterToInchAndFoot(meters, foot, inch);

    cout << "Distance in feet and inches: " << foot << " feet, " << inch << " inches" << endl;
    return 0;
    */

    /* exercise 3
    cout << "Enter a float number: ";
    double number;
    cin >> number;
    cout << "The nearest integer number is " << roundToNearestInt(number) << endl;
    return 0;
    */

    /* exercise 4
    for (double v = 5; v <= 60; v += 5 ) {
        for (double t = 40; t >= -45; t -= 5) {
               cout << setw(4) << roundToNearestInt(windChill(t, v));
        }
        cout << endl;
    }
    */

   /* exercise 5
    for (int i = 1; i <= 9999; i ++) {
        if (isPerfect(i)) cout << i << endl;
    }
   */

    /* exercise 6
    for (int i = 0; i < 100; i++) {
        if (isPrime(i)) cout << i << " ";
    }
    cout << endl;
    */

    /* exercise 7
    cout << "Enter a number: ";
    double number;
    cin >> number;
    cout << "The square root is " << sqrtN(number) << endl;
    cout << "The standard library square root is " << sqrt(number) << endl;
    return 0;
    */

    /* exercise 8
    cout << "Enter a year(1700-1899): ";
    int year;
    cin >> year;
    string month;
    int day;
    findEaster(year, month, day);
    cout << "The date of Easter: " << month << " " << day << endl;
    return 0;
    */

    /* exercise 9
    cout << "Choose k values from a set of n elements p(n, k): ";
    int n, k;
    cin >> n >> k;

    cout << "permutations: " << permutations(n, k);
    return 0;
    */

    /*
     * Finsh exercise 10 and exercise 11 in other files.
     */

    /* exercise 12
    cout << "Enter a number you want to trials: ";
    int number;
    cin >> number;
    double sum = 0;
    for (int i = 0; i < number; i++) {
        sum += randomReal(0, 1);
    }
    cout << "Average fater a specified number: " << sum /number;
    return 0;
    */

    /*
     * exercise 13
     * a sample that contains 10000 atoms of radioactive material
     */
    /*
    int year = 0;
    int total = 10000;
    cout << "There are 10000 atoms initially." << endl;
    while (total != 0) {
        int left = 0;
        for (int i = 0; i < total; i++) {
            if (randomChance(0.5)) left++;
        }
        total = left;
        year++;
        cout << "There are " << total << " atoms at the end of year " << year << "." << endl;
    }
    */

    /* exercise 14
    int count = 0;
    for (int i = 0; i < 10000; i++) {
        double a = randomReal(-1, 1);
        double b = randomReal(-1, 1);
        if (sqrt(a*a + b*b) < 1) count++;
    }
    cout << "fall within the circle: " << count/10000.0;
    */

    /* exercise 15
    int number = 0;
    while (true) {
        number++;
        if (randomChance(0.5)) {
            cout << "heads" << endl;
            number++;
            if (randomChance(0.5)) {
                cout << "heads" << endl;
                number++;
                if (randomChance(0.5)) {
                    cout << "heads" << endl;
                    cout << "It took " << number << " filps to get 3 consecutive heads." << endl;
                    return 0;
                } cout << "tails " << endl;
            } else
                cout << "tails" << endl;
        }
        else
            cout << "tails" << endl;
    }
    */

    /* exercise 16
    GWindow gw(400, 200);
    double width = gw.getWidth();
    double height = gw.getHeight();
    gw.setColor("CYAN");
    gw.fillRect(0, 0, width, height);
    gw.setColor("RED");
    gw.fillOval(-width/8, height/8-10, width*1.25, height*1.25);
    gw.setColor("ORANGE");
    gw.fillOval(-width/8, height/8*2-10, width*1.25, height*1.25);
    gw.setColor("YELLOW");
    gw.fillOval(-width/8, height/8*3-10, width*1.25, height*1.25);
    gw.setColor("GREEN");
    gw.fillOval(-width/8, height/8*4-10, width*1.25, height*1.25);
    gw.setColor("BLUE");
    gw.fillOval(-width/8, height/8*5-10, width*1.25, height*1.25);
    gw.setColor("MAGENTA");
    gw.fillOval(-width/8, height/8*6-10, width*1.25, height*1.25);
    gw.setColor("CYAN");
    gw.fillOval(-width/8, height/8*7-10, width*1.25, height*1.25);
    */

    /* exercise 17
    GWindow gw(240, 240);
    double width = gw.getWidth();
    double height = gw.getHeight();
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            if ((i+j)%2 != 0) {
                gw.setColor("CYAN");
                gw.fillRect(j*width/8, i*height/8, width/8, height/8);
            }
        }
    }

    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 8; j++) {
            if ((i+j)%2 != 0) {
                gw.setColor("RED");
                gw.fillOval(j*width/8 + width/80, i*height/8 + height/80, width/10, height/10);
            }
        }
    }

    for (int i = 5; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            if ((i+j)%2 != 0) {
                gw.setColor("BLACK");
                gw.fillOval(j*width/8 + width/80, i*height/8 + height/80, width/10, height/10);
            }
        }
    }
    return 0;
    */

    GWindow gw(300, 300);
    gw.setTitle("Taoist philosophy");
    double width = gw.getWidth();
    double height = gw.getHeight();

    gw.setColor("BLACK");
    gw.fillOval(15, 15, width -30, height - 30);
    gw.setColor("White");
    gw.fillRect(0, 0, width/2, height);
    gw.setColor("BLACK");
    gw.drawOval(15, 15, width - 30, height -30);

    // big circle
    gw.setColor("WHITE");
    gw.fillOval(7.5+width/4, 15, (width-30)/2, (height-30)/2);
    gw.setColor("BLACK");
    gw.fillOval(7.5+width/4, height/2, (width-30)/2, (height-30)/2);

    // small circle
    gw.setColor("BLACK");
    gw.fillOval(width/2 - 15, height/4 -15, 15, 15);
    gw.setColor("WHITE");
    gw.fillOval(width/2 - 15, height/4*3 - 15, 15, 15);
    return 0;

}

/*
int permutations(int n, int k) {
    int multi = 1;
    for (int i = n; i > k; i--) {
        multi *= i;
    }
    return multi;
}
*/
void findEaster(int year, string & month, int & day) {
    int a = (year / 19 % 2 == 0) ? 0 : year % 19;
    int b = (year / 4 % 2 == 0) ? 0 : year % 4;
    int c = (year / 7 % 2 == 0) ? 0 : year % 7;

    int d = (19 * a + 23) % 30;
    int e;
    if (year >= 1700 & year <= 1799) {
        e = (2 * b + 4 * c + 6 * d + 3) % 7;
    }
    if (year >= 1800 & year <= 1899) {
        e = (2 * b + 4 * c + 6 * d + 4) % 7;
    }

    if (d + e > 9) {
        month = "April";
        day = d + e - 9;
    } else {
        month = "March";
        day = 22 + d + e;
    }
}

double sqrtN(double x) {
    double k = x/2;
    while (fabs(k*k - x) > 1e-9) {
        k = 0.5*(k+x/k);
    }
    return k;
}


bool isPrime(int number) {
    for (int i = 2; i < number; i++) {
        if (number % i == 0) return false;
    }
    return true;
}

bool isPerfect(int number) {
    int sum = 0;
    for (int i = 1; i < number; i++) {
        if (number % i == 0) {
                sum += i;
        }
    }
    if (sum == number) return true;
    return false;
}

double windChill(double t, double v) {
    if (v == 0) return t;
    if (t > 40) error("undefined");
    return 35.74 + 0.6215 * t - 35.75 * pow(v, 0.16) + 0.4275 * t * pow(v, 0.16);
}

double celsiusToFahrenheit(double celsius) {
    return celsius * 9.0 / 5 + 32;
}

void meterToInchAndFoot(double meter, int &foot, int &inch) {
    inch = int (meter / 0.0254);
    foot = inch / 12;
    inch = inch % 12;
}

int roundToNearestInt(double x) {
    if ( x > 0)
        return (int)(x + 0.5);
    else
        return (int)(x - 0.5);
}

/*
 * output
 *
 * exercise 1
 *Enter a temperature in degrees Celsius: 32
 *Corresponding temperature in degrees Fahrenheit: 89.6
 *
 * exercise 2
 * Enter a distance in meters: 32
 * Distance in feet and inches: 104 feet, 11 inches
 *
 * exercise 3
 * Enter a float number: 0.5
 * The nearest integer number is 1
 * Enter a float number: -0.4
 * The nearest integer number is 0
 *
 * exercise 4
 * 36  31  25  19  13   7   1  -5 -11 -16 -22 -28 -34 -40 -46 -52 -57 -63
 * 34  27  21  15   9   3  -4 -10 -16 -22 -28 -35 -41 -47 -53 -59 -66 -72
 * 32  25  19  13   6   0  -7 -13 -19 -26 -32 -39 -45 -51 -58 -64 -71 -77
 * 30  24  17  11   4  -2  -9 -15 -22 -29 -35 -42 -48 -55 -61 -68 -74 -81
 * 29  23  16   9   3  -4 -11 -17 -24 -31 -37 -44 -51 -58 -64 -71 -78 -84
 * 28  22  15   8   1  -5 -12 -19 -26 -33 -39 -46 -53 -60 -67 -73 -80 -87
 * 28  21  14   7   0  -7 -14 -21 -27 -34 -41 -48 -55 -62 -69 -76 -82 -89
 * 27  20  13   6  -1  -8 -15 -22 -29 -36 -43 -50 -57 -64 -71 -78 -84 -91
 * 26  19  12   5  -2  -9 -16 -23 -30 -37 -44 -51 -58 -65 -72 -79 -86 -93
 * 26  19  12   4  -3 -10 -17 -24 -31 -38 -45 -52 -60 -67 -74 -81 -88 -95
 * 25  18  11   4  -3 -11 -18 -25 -32 -39 -46 -54 -61 -68 -75 -82 -89 -97
 * 25  17  10   3  -4 -11 -19 -26 -33 -40 -48 -55 -62 -69 -76 -84 -91 -98
 *
 * exercise 5
 * 6
 * 28
 * 496
 * 8128
 *
 * exercise 6
 * 0 1 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97
 *
 * exercise 7
 * Enter a number: 2
 * The square root is 1.41421
 * The standard library square root is 1.41421
 *
 * exercise 8
 * Enter a year(1700-1899): 1755
 * The date of Easter: April 15
 *
 * exercise 9
 * Choose k values from a set of n elements p(n, k): 3 2
 * permutations: 3
 *
 *
 * exercise 12
 * Enter a number you want to trials: 3
 * Average fater a specified number: 0.619592
 *
 * exercise 13
 * There are 10000 atoms initially.
 * There are 4961 atoms at the end of year 1.
 * There are 2418 atoms at the end of year 2.
 * There are 1201 atoms at the end of year 3.
 * There are 594 atoms at the end of year 4.
 * There are 281 atoms at the end of year 5.
 * There are 134 atoms at the end of year 6.
 * There are 60 atoms at the end of year 7.
 * There are 32 atoms at the end of year 8.
 * There are 10 atoms at the end of year 9.
 * There are 6 atoms at the end of year 10.
 * There are 2 atoms at the end of year 11.
 * There are 1 atoms at the end of year 12.
 * There are 0 atoms at the end of year 13.
 *
 * exercise 14
 * fall within the circle: 0.783
 *
 * exercise 15
 * tails
 * tails
 * heads
 * tails
 * heads
 * tails
 * heads
 * tails
 * heads
 * heads
 * heads
 * It took 11 filps to get 3 consecutive heads.
 *
 * exercise 16
 * graphics display, done!
 *
 * exercise 17
 * graphics display, done!
 *
 * exercise 18
 * graphics display, done!
 * 
 */

第三章 String类

3.1 Using strings as abstract values

3.2 String operations

3.3 The library

3.4 Modifying the contents of a string

3.5 The legacy of C-style strings

3.6 Writing string applictions

3.7 The strlib.h library

本章主要介绍String类,介绍类中常用的方法。

练习题

1. 字符表示一个字母,字符串表示一串字符
2. false
3. getline(cin, string);
4. 方法属于类中的方法,自由函数可以随意调用。
5. false, str.length();
6. s1
7. 两个字符串连接。
8. 每个字母出现的先后顺序。
9. string.at(i), string[i] 函数与字符重载
10. no difference
12. true
13. first and last letter,到结尾。
14. string::npos.
15. 重复的题目。
16. size_t
17. 5, 0, C, ABCDE, a, ZZCDE, ABC, E, DE, ""
18. for (int i = 0; i < str.length(); i++) {}
19. for (int i = str.length() - 1; i >= 0; i--) {}
20. +
21. 0, 1, 0, 7, 65, 97(出乎意料)
22. 与C兼容

23. str = "abc"; str.c_str(); 

#include 
#include 
#include "console.h"

using namespace std;

bool isVowel(char ch) {
    switch(ch) {
    case 'A': case 'E': case 'I': case 'O': case 'U':
    case 'a': case 'e': case 'i': case 'o': case 'u':
        return true;
    default:
        return false;
    }
}

int findFirstVowel(string word) {
    for (int i = 0; i < word.length(); i++) {
        if (isVowel(word[i])) return i;
    }
    return -1;
}

string wordToPigLatin(string word) {
    int vp = findFirstVowel(word);
    if (vp == -1) {
        return word;
    } else if (vp == 0) {
        return word + "way";
    } else {
        string head = word.substr(0, vp);
        string tail = word.substr(vp);
        return tail + head + "ay";
    }
}

// Translates each word in the line to Pig Latin, leaving all other
// characters unchanged.
string lineToPigLatin(string line) {
    string result;
    int start = -1;
    for (int i = 0; i < line.length(); i++) {
        char ch = line[i];
        if (isalpha(ch)) {
            if (start == -1) start = i;
        } else {
            if (start >= 0) {
                result += wordToPigLatin(line.substr(start, i - start));
                start = -1;
            }
            result += ch;
        }
    }
    if (start >= 0) result += wordToPigLatin(line.substr(start));
    return result;
}

bool endWith(string str, string suffix) {
    if (str.length() < suffix.length()) return false;
    for (int i = str.length() - suffix.length(); i < str.length(); i++) {
        if (str[i] != suffix[i -str.length() + suffix.length()]) return false;
    }
    return true;
}

int main() {
    /* This version of the program reads a complete line into name and
     * not just the first word.
    string name;
    cout << "Enter your full name: ";
    getline(cin, name);
    cout << "Hello, " << name << "!" << endl;
    return 0;
    */

    /*
    cout << "This program translates English to Pig Latin." << endl;
    string line;
    cout << "Enter English text: ";
    getline(cin, line);
    string translation = lineToPigLatin(line);
    cout << "Pig Latin output: " << translation << endl;
    return 0;
    */

    /* exercise 1
    cout << endWith("wangrl", "rl") << endl;
    return 0;
    */



}

/*
 * reference
 * Enter your full name: wang rl
 * Hello, wang rl!
 *
 * This program translates English to Pig Latin.
 * Enter English text: wangrl helloworld!
 * Pig Latin output: angrlway elloworldhay!
 */

/*
 * output
 *
 * exercise 1
 * 1
 */

#include 
#include 


using namespace std;
void error(string msg) {
    cerr << msg << endl;
    exit(EXIT_FAILURE);
}


string trim(string str) {
    string result = "";
    for (int i = 0; i < str.length(); i++) {
        if (str[i] != ' ' && str[i] != '\r') {
            result += str[i];
        }
    }
    return result;
}

string substr(string str, int pos, int n) {
    if (n > str.length()) n = str.length();
    if (pos > str.length()) error("length: pos > str");

    string result = "";
    for (int i = pos; i < n; i++) {
        result += str[i];
    }
    return result;
}

string capitalize(string str) {
    string result = "";
    if(isalpha(str[0])) {
        result += toupper(str[0]);
        for (int i = 1; i < str.length(); i++) {
            result += tolower(str[i]);
        }
        return result;
    } else {
        return str;
    }
}

int letterPoints(char c) {
    switch(c) {
    case 'A': case 'E': case 'I':
    case 'L': case 'N': case 'O':
    case 'R': case 'S': case 'T':
    case 'U':
        return 1;
    case 'D': case 'G':
        return 2;
    case 'B': case 'C': case 'M': case 'P':
        return 3;
    case 'F': case 'H': case 'V': case 'W': case 'Y':
        return 4;
    case 'K':
        return 5;
    case 'J': case 'X':
        return 8;
    case 'Q': case 'Z':
        return 10;
    default:
        return 0;
    }
}

int stringPoints(string str) {
    int total = 0;
    for (int i = 0; i < str.length(); i++) {
        total += letterPoints(str[i]);
    }
    return total;
}

char firstChar(string str) {
    return str[0];
}

string lineToChar(string line) {
    string result;
    int start = -1;
    for (int i = 0; i < line.length(); i++) {
        char ch = line[i];
        if (isalpha(ch)) {
            if (start == -1) start = i;
        } else {
            if (start >= 0) {
                result += firstChar(line.substr(start, i - start));
                start = -1;
            }
            // result += ch;
        }
    }
    if (start >= 0) result += firstChar(line.substr(start));
    return result;
}


string removeCharacters(string str, string remove) {
    string contain = str;
    for (int i = 0; i < remove.length(); i++) {
        for (int j = 0; j < str.length(); j++) {
            if (str[j] == remove[i]) contain[j] = '0';
        }
    }
    string result = "";
    for (int k = 0; k < str.length(); k++) {
        if (contain[k] != '0') result += contain[k];
    }
    return result;
}

void removeCharactersInPlace(string &str, string remove) {
    for (int i = 0; i < remove.length(); i++) {
        for (int j = 0; j < str.length(); j++) {
            if (str[j] == remove[i]) str[j] = '0';
        }
    }
    string result = "";
    for (int k = 0; k < str.length(); k++) {
        if (str[k] != '0') result += str[k];
    }
    str = result;
}

int main(int argc, char *argv[])
{
    /* exercise 2
     * output
     * wangrl
    cout <<  trim("wang rl") << endl;
    return 0;
    */

    /* exercise 3
     * output
     * ng
     *
    cout << substr("wangrl", 2, 4) << endl;
    */

    /* exercise 4
     * output
     * Boolean
     * Boolean
    cout << capitalize("BOOLEAN") << endl;
    cout << capitalize("boolean") << endl;
    */

    /*exercise 5
     * output
     * 9
    cout << stringPoints("FARM") << endl;
     */

    /* exercise 6
     * output
     * scuba
     * AIDS
    cout << lineToChar("self-contained underwater breathing apparatus") << endl;
    cout << lineToChar("Acquired Immune Deficiency Syndrome") << endl;
    */

    /* exercise 7
     * output
     * cntrrvltnrs
    cout << removeCharacters("counterrevolutionaries", "aeiou") << endl;
    */

    /* exercise 8
     * output
     * cntrrvltnrs
    string str = "counterrevolutionaries";
    removeCharactersInPlace(str, "aeiou");
    cout << str << endl;
    */   
}

#include 
#include 
#include "console.h"
#include 

using namespace std;

string removeDoubledLetters(string str) {
    char a = str[0];
    char b = str[0];
    string result;
    for (int i = 0; i < str.length() - 1; i++) {
        a = char(str[i]);
        b = char (str[i + 1]);
        if (a != b)
            result += str[i];
    }
    result += str.at(str.length() - 1);
    return result;
}

string replaceAll(string str, char c1, char c2) {
    for (int i = 0; i < str.length(); i++) {
        if (str[i] == c1)
            str[i] = c2;
    }
    return str;
}

string replaceAll(string str, string s1, string s2) {
    string result = "";
    for (int i = 0; i < str.length(); i++) {
        int n = str.find(s1, i);
        if (i != n) result += str[i];
        else {
            i += s1.length() - 1;
            result += s2;
        }
    }
    return result;
}

bool isSentencePalindrome(string str) {
    string beginSentence = "";
    for (int i = 0; i < str.length(); i++) {
        if (isalpha(str[i])) beginSentence += tolower(str[i]);
    }
    string endSentence = "";
    for (int i = str.length()-1; i >= 0; i--) {
        if (isalpha(str[i])) endSentence += tolower(str[i]);
    }
    for (int i = 0; i < beginSentence.length(); i++) {
        if (beginSentence[i] != endSentence[i]) return false;
    }
    return true;
}

bool isVowel(char c) {
    return c == 'a' || c == 'e' || c == 'i' || c =='o' || c == 'u' ||
            c == 'A' || c == 'E' || c == 'I' || c =='O' || c == 'U';
}

string createRegularPlural(string word) {
    char lastChar = word[word.length() - 1];
    char penultChar = word[word.length() - 2];
    if (lastChar == 's' || lastChar =='z' || lastChar == 'z' ||
            (lastChar == 'h' &&(penultChar == 'c' || penultChar == 's'))) {
        return word + "es";
    } else if (lastChar == 'y' && !isVowel(penultChar)){
        return word.replace(word.length()-1, 1, "ies");
    } else {
        return word + "s";
    }
}

int main()
{
    /* exercise 9
    cout << removeDoubledLetters("bookkeeper") << endl;
    cout << removeDoubledLetters("committee") << endl;
    */

    /* exercise 10
    cout << replaceAll("nannies", 'n', 'd');
    cout << replaceAll("wangrl", "an", "rlt") << endl;
    */

    /* exercise 11
    cout << "This program tests for sentence palindromes." << endl;
    cout << "Indicate the end of the input with a blank line." << endl;
    string str;
     cout << "Enter a sentence: ";
   while(getline(cin, str) && str !="") {
        if (isSentencePalindrome(str)) {
            cout << "That sentence is a palindrome." << endl;
        } else {
            cout << "That sentence is not a palindrome." << endl;
        }
        cout << "Enter a sentence: ";
    }
    */

    cout << createRegularPlural("wangrl") << endl;
    cout << createRegularPlural("cheery") << endl;
    cout << createRegularPlural("lay") << endl;

    return 0;
}

/*
 *
 *
 * output
 * exercise 9
 * bokeper
 * comite
 *
 * exercise 10
 * daddies
 * wrltgrl
 *
 * exercise 11
 * This program tests for sentence palindromes.
 * Indicate the end of the input with a blank line.
 * Enter a sentence: Madam, I'm Adam.
 * That sentence is a palindrome.
 * Enter a sentence: A man, a plan, a canal -- Panama!
 * That sentence is a palindrome.
 * Enter a sentence: Not a palindrome.
 * That sentence is not a palindrome.
 * Enter a sentence:
 *
 * exercise 12
 * wangrls
 * cheeries
 * lays
 *
 */
#include 
#include 
#include 
#include 

using namespace std;

string itos(int i) {
   stringstream s;
   s << i;
   return s.str();
}

string ctos(char c) {
    stringstream s;
    s << c;
    return s.str();
}

string createOrdinalForm(int n) {
    switch(n) {
    case 1:
        return "1st";
    case 2:
        return "2nd";
    case 3:
        return "3rd";
    default:
        return itos(n) +"th";
    }
}

string addCommas(string digits) {
    if (digits.length() < 3) return digits;
    int length = digits.length();
    string result = "";
    int i;
    for (i = length; i > 3; i -= 3) {
        result = "," + ctos(digits[i-3]) + ctos(digits[i-2]) + ctos(digits[i-1]) + result;
    }
    i--;
    for (; i >= 0; i--)
        result = ctos(digits[i]) + result;
    return result;
}

bool isVowel(char ch) {
    switch(ch) {
    case 'A': case 'E': case 'I': case 'O': case 'U':
    case 'a': case 'e': case 'i': case 'o': case 'u':
        return true;
    default:
        return false;
    }
}

int findFirstVowel(string word) {
    for (int i = 0; i < word.length(); i++) {
        if (isVowel(word[i])) return i;
    }
    return -1;
}

string wordToPigLatin(string word) {
    bool upperCase = isupper(word[0]);
    word[0] = tolower(word[0]);
    int vp = findFirstVowel(word);
    if (vp == -1) {
        if (upperCase) word[0] = toupper(word[0]);
        return word;
    } else if (vp == 0) {
        if (upperCase) word[0] = toupper(word[0]);
        return word + "way";
    } else {
        string head = word.substr(0, vp);
        string tail = word.substr(vp);
        if (upperCase) tail[0] = toupper(tail[0]);
        return tail + head + "ay";
    }
}

// Translates each word in the line to Pig Latin, leaving all other
// characters unchanged.
string lineToPigLatin(string line) {
    string result;
    int start = -1;
    for (int i = 0; i < line.length(); i++) {
        char ch = line[i];
        if (isalpha(ch)) {
            if (start == -1) start = i;
        } else {
            if (start >= 0) {
                result += wordToPigLatin(line.substr(start, i - start));
                start = -1;
            }
            result += ch;
        }
    }
    if (start >= 0) result += wordToPigLatin(line.substr(start));
    return result;
}

string obenglobish(string word) {
    string result = "";
    for (int i = 0; i < word.length() - 1; i++) {
        bool vowelLetter = isVowel(word[i]) && !(isVowel(word[i+1]) && word[i] != word[i+1]);
        if (vowelLetter && (i != 0)) vowelLetter = !(isVowel(word[i]) && isVowel(word[i-1]));
        if (vowelLetter) {
            result += "ob" + ctos(word[i]);
        } else {
            result += ctos(word[i]);
        }
    }
    if (isVowel(word[word.length()-1]) && word[word.length()-1] != 'e' && !isVowel(word[word.length()-2])) {
        result += "ob" + ctos(word[word.length()-1]);
    } else {
        result += ctos(word[word.length()-1]);
    }
    return result;
}

string encodeCaesarCipher(string str, int shift) {
    while (shift < 0) {
        shift += 26;
    }
    string result = "";
    for (int i = 0; i < str.length(); i++) {
        if (isalpha(str[i]))  {
            if (isupper(str[i]))
                str[i] = (str[i] - 'A' + shift) % 26 + 'A';
            else {
                        str[i] = (str[i] - 'a' + shift) % 26 + 'a';
             }
        }
        result += str[i];
     }
    return result;
}

int main(int argc, char *argv[])
{
    /* exercise 13
    cout << createOrdinalForm(2) << endl;
    cout << createOrdinalForm(14) << endl;
    */

    /* exercise 14
    while (true) {
        string digits;
        cout << "Enter a number: ";
        getline(cin, digits);
        if (digits == "") break;
        cout << addCommas(digits) << endl;
    }
    */

    /* exercise 15
    cout << "This program translates English to Pig Latin." << endl;
    string line;
    cout << "Enter English text: ";
    getline(cin, line);
    string translation = lineToPigLatin(line);
    cout << "Pig Latin output: " << translation << endl;
    return 0;
    */

    /* exercise 16
    while (true) {
        string word;
        cout << "Enter a word: ";
        getline(cin, word);
        if (word == "") break;
        string trans = obenglobish(word);
        cout << word << " -> " << trans << endl;
    }
    */

    cout << "This program encodes a message using a Caesar cipher." << endl;
    cout << "Enter the number of character positions to shift: ";
    int number;
    cin >> number;
    getchar();
    cout << "Enter a message: ";
    string str;
    getline(cin, str);
    cout << "Encoded meassage: " << encodeCaesarCipher(str, number) << endl;
    return 0;
}

/*
 * output
 *
 * exercise 13
 * 2nd
 * 14th
 *
 * exercise 14
 * Enter a number: 17
 * 17
 * Enter a number: 1001
 * 1,001
 * Enter a number: 12345678
 * 12,345,678
 * Enter a number: 999999999
 * 999,999,999
 * Enter a number:
 *
 * exercise 15:
 * This program translates English to Pig Latin.
 * Enter English text: This is Pig Latin.
 * Pig Latin output: Isthay isway Igpay Atinlay.
 *
 * exercise 16
 * Enter a word: english
 * english -> obenglobish
 * Enter a word: hobnob
 * hobnob -> hobobnobob
 * Enter a word: gooiest
 * gooiest -> gobooiest
 * Enter a word: amaze
 * amaze -> obamobaze
 * Enter a word: rot
 * rot -> robot
 * Enter a word:
 *
 * exercise 17
 * This program encodes a message using a Caesar cipher.
 * Enter the number of character positions to shift: 13
 * Enter a message: This is a secret message.
 * Encoded meassage: Guvf vf n frperg zrffntr.
 * 
 * This program encodes a message using a Caesar cipher.
 * Enter the number of character positions to shift: -1
 * Enter a message: IBM 9000
 * Encoded meassage: HAL 9000
 */
#include 
#include 
using namespace std;

string letterSubstitution(string str, string cipher) {
    for (int i = 0; i < str.length(); i++) {
        if (isalpha(str[i]))
              str[i] = cipher[str[i] - 'A'];
    }
    return str;
}

string invertKey(string decrypt, string key) {
    for (int i = 0; i < decrypt.length(); i++) {
        if (isalpha(decrypt[i])) {
            for (int j = 0; j < key.length(); j++) {
                if (key[j] == decrypt[i])  {
                    decrypt[i] = 'A' + j;
                    break;
                }
            }
        }
    }
    return decrypt;
}

int findDNAMatch(string s1, string s2, int start = 0) {
   string s3 = "";
   for (int i = 0; i < s2.length(); i++) {
       if (s2[i] == 'A')
           s2[i] = 'T';
       else if (s2[i] == 'T')
           s2[i] = 'A';
       else if (s2[i] == 'C')
           s2[i] = 'G';
       else
           s2[i] = 'C';
   }
   return s2.find(s1, start);
}

int main(int argc, char *argv[])
{
    /* exercise 18
    cout << "Letter substitution cipher." << endl;
    cout << "Enter a 26-letter key: ";
    string cipher;
    getline(cin, cipher);
    cout << "Enter a message: ";
    string message;
    getline(cin, message);
    cout << "Encoded message: " << letterSubstitution(message, cipher);
    */

    /* exercise 19
    string key = "QWERTYUIOPASDFGHJKLZXCVBNM";
    string decrypt = "VGKATKL GY ZIT VGKSR XFOZT!";
    cout << invertKey(decrypt, key) << endl;
    return 0;
    */

    string s2 = "TAACGGTACGTC";
    string s1 = "TGC";
    cout << findDNAMatch(s1, s2) << endl;
    cout << findDNAMatch(s1, s2, 5) << endl;
}

/*
 * output
 * exercise 18
 * Letter substitution cipher.
 * Enter a 26-letter key: QWERTYUIOPASDFGHJKLZXCVBNM
 * Enter a message: WORKERS OF THE WORLD UNITE!
 * Encoded message: VGKATKL GY ZIT VGKSR XFOZT!
 *
 * exercise 19
 * WORKERS OF THE WORLD UNITE!
 *
 * exercise 20
 * 2
 * 7
 */

第四章 输入输出

4.1 Using strings as abstract values

4.2 Formatted input

4.3 Data files

4.4 Class hierarchies

4.5 The simpio. and filelib.h libraries

主要讲标准卡的输入输出,然后结合便利性创建自己的输入输出。

复习题
1. fstream sstream iostream
2. 输出/输入流
3. 输出/输入的对象,可以连续输入。
4. 控制输出的属性
5. 短暂性,持久性
6. 固定,科学计数,默认
7. default, setprecision(6), scientific,
   scientific setprecision(6),
   setw(16) right setprecision(9),
   %0.4f
8. 文件输入输出流
9. c_str
10. fail()函数
11. get(ch) != EOF
12. 返回错误
13. 把获取的字符回退到流中
14. 行不为空
15. istringstream, ostringstream, 字符串和文件
16. 子类,父类,继承
17. true
18. 可以使用其它流
19. 全部概括到函数中
20. 阅读.h文件

#include 
#include 
#include 
using namespace std;

const double PI = 3.14159265358979323846;
const double SPEED_OF_LIGHT = 2.99792458E+8;
const double FINE_STRUCTURE = 7.2573525E-3;

void printPrecisionTable();

int main(int argc, char *argv[])
{
    /* 4.1
     * formatted output
    cout << uppercase << right;
    cout << "Default format:" << endl << endl;
    printPrecisionTable();
    cout << endl << "Fixed format:" << fixed << endl << endl;
    printPrecisionTable();
    cout << endl << "Scientific format:" << scientific << endl << endl;
    printPrecisionTable();
    */
    
    
    return 0;
}

void printPrecisionTable() {
    cout << " prec  |     pi     | speed of light   | fine-structure" << endl;
    cout << "---------+----------+-----------------------+---------------------" << endl;
    for (int prec = 0; prec <= 6; prec += 2) {
        cout << "  " << setw(12) << setprecision(prec) << PI << " |";
         cout << "  " << setw(16) << setprecision(prec) << SPEED_OF_LIGHT << " |";
         cout << " " << setw(14) << setprecision(prec) << FINE_STRUCTURE << endl;
    }
}

/*
 * output
 * 4.1
 * Default format:
 *
 * prec  |     pi     | speed of light   | fine-structure
 * ---------+----------+-----------------------+---------------------
             3 |             3E+08 |          0.007
           3.1 |             3E+08 |         0.0073
         3.142 |         2.998E+08 |       0.007257
       3.14159 |       2.99792E+08 |     0.00725735

 * Fixed format:

  * prec  |     pi     | speed of light   | fine-structure
  * ---------+----------+-----------------------+---------------------
             3 |         299792458 |              0
          3.14 |      299792458.00 |           0.01
        3.1416 |    299792458.0000 |         0.0073
      3.141593 |  299792458.000000 |       0.007257

  * Scientific format:

  * prec  |     pi     | speed of light   | fine-structure
  * ---------+----------+-----------------------+---------------------
         3E+00 |             3E+08 |          7E-03
      3.14E+00 |          3.00E+08 |       7.26E-03
  *   3.1416E+00 |        2.9979E+08 |     7.2574E-03
  * 3.141593E+00 |      2.997925E+08 |   7.257352E-03
  * 
  */
/*
 * This program displays the contents of a file chosen by the user.
 */
#include 
#include 
#include 
using namespace std;

string promptUserForFile(ifstream &infile, string prompt = "") {
    while (true) {
        cout << prompt;
        string filename;
        getline(cin, filename);
        infile.open(filename.c_str());
        if (!infile.fail()) return filename;
        infile.clear();
        cout << "Unable to open that file. Try again." << endl;
        if (prompt == "") prompt = "Input file: ";
    }
}

int main() {
    /* file i/o
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    char ch;
    while (infile.get(ch)) {
        cout.put(ch);
    }
    infile.close();
    return 0;
    */
}

/*
 * output
 * Input file: Jabberwocky
 * Unable to open that file. Try again.
 * Input file: Jabberwocky.txt 
 * 'Twas brillig, and the slithy toves
 * Did gyre and gimble in the wabe;
 * All mimsy were the borogoves,
 * And the mome raths outgrabe.
 */

后面的编程题中会用到 program.txt

/*
 * This program displays the contents of a file chosen by the user.
 */

#include
using namespace std;

int main() {
    int a, b, c;  // define three variable;
    b = 1; c = 2;
    // add
    a = a + b;
    /* output */
    cout << a << endl;
    return 0;
}

#include 
#include 
#include 
#include 
#include 
#include "console.h"
#include "error.h"
#include "filelib.h"
#include "simpio.h"

using namespace std;

const double PI = 3.14159265358979323846;

int roundToNearestInt(double x) {
    if ( x > 0)
        return (int)(x + 0.5);
    else
        return (int)(x - 0.5);
}

double windChill(double t, double v) {
    if (v == 0) return t;
    if (t > 40) error("undefined");
    return 35.74 + 0.6215 * t - 35.75 * pow(v, 0.16) + 0.4275 * t * pow(v, 0.16);
}

string longestLine(ifstream &infile, string prompt = "") {
    string str;
    string result;
    unsigned int number = 0;
    while (getline(infile, str)) {
        if (str.length() > number) {
            number = str.length();
            result = str;
        }
    }
    infile.close();
    return result;
}

string getRoot(string filename) {
    string root = "";
    for (int i = 0; i < filename.length(); i++) {
        if (filename[i] == '.') break;
        root += filename[i];
    }
    return root;
}

string getExtension(string filename) {
    string dot = ".";
    string extension = "";
    int firstDot = filename.find(dot);
    for (int i = firstDot+1; i < filename.length(); i++) {
        extension += filename[i];
    }
    return extension;

}

string defaultExtension(string filename, string ext) {
    string result = "";
    if (filename.find(".") == string::npos) return filename + ext;
    if (filename.find(".") > 0 && ext.find("*.") == string::npos) return filename;
    if (filename.find(".") > 0 && ext.find("*.") >= 0) {
        int number = filename.find(".");
        for (int i = 0; i < number; i++) {
            result += filename[i];
        }
        result += ".";
        for (int i = 2; i < ext.length(); i++) {
            result += ext[i];
        }
    }
    return result;
}

void removeComments(istream &is, ostream &os) {
    string str;
    bool isComment = true;
    while (getline(is, str)) {
        if (str.find("//") != string::npos && str.find("*/") == string::npos) {
            int number = str.find("//");
            for (int i = 0; i < number; i++) {
                os << str[i];
            }
            cout << endl;
        }

        else if (str.find("/*") != string::npos && str.find("*/") == string::npos) {
            int number = str.find("/*");
            for (int i = 0; i < number; i++) {
                os << str[i];
            }
            isComment = true;
        }
        else if (str.find("*/") != string::npos) {
            int number = str.find("*/");
            for (int i = number + 2; i < str.length(); i++) {
                os << str[i];
            }
            isComment = false;
        }
        else if (!isComment) {
            os << str << endl;
        }
    }
}

string removeCharacters(string str, string remove) {
    string contain = str;
    for (int i = 0; i < remove.length(); i++) {
        for (int j = 0; j < str.length(); j++) {
            if (str[j] == remove[i]) contain[j] = '0';
        }
    }
    string result = "";
    for (int k = 0; k < str.length(); k++) {
        if (contain[k] != '0') result += contain[k];
    }
    return result;
}

/*
double stringToReal(const std::string& str) {
    std::istringstream stream(str);
    double value;
    stream >> value;
    if (stream.fail() || !stream.eof()) {
        error("stringToReal: Illegal floating-point format (" + str + ")");
    }
    return value;
}

std::string realToString(double d) {
    std::ostringstream stream;
    stream << std::uppercase << d;
    return stream.str();
}
*/

int main() {
    /* exercise 1
    cout << "  theta  |  sin(theta)  |  cos(theta)  |" << endl;
    for (double i = -90; i <= 90; i+=15) {
        cout.unsetf(std::ios_base::floatfield);
        cout << "   " << setw(3) << i << "   " << "|";
        cout << "  " << setw(10) << fixed << setprecision(7) << sin(i/180*PI) << "  |   ";
        cout << cos(i/180*PI) << "  |" << endl;

    }
    */

    /* exercise 2
    for (double v = 5; v <= 60; v += 5 ) {
        for (double t = 40; t >= -45; t -= 5) {
               cout << setw(4) << roundToNearestInt(windChill(t, v));
        }
        cout << endl;
    }
    */

    /* exercise 3
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    cout << "Longest line: " << longestLine(infile) << endl;
    */

    /* exercise 4
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    int nChars = 0;
    int nWords = 0;
    int nLines = 0;
    string str;
    while (getline(infile, str)) {
        nLines++;
        for (int i = 0; i < str.length(); i++) {
            nChars++;
        }
        nChars++;

        for (int i = 0; i < str.length() - 1; i++) {
            if (isspace(str[i])&&!isspace(str[i+1])) nWords++;
        }
        nWords++;
    }
    infile.close();

    int length = 0;
    int count = nChars;
    while (count % 10 != 0) {
        count /= 10;
        length++;
    }
    cout << "Chars: " << setiosflags(ios::right) << setw(length) << nChars << endl;
    cout << "Words: " << setiosflags(ios::right) << setw(length) << nWords << endl;
    cout << "Lines: " << setiosflags(ios::right) << setw(length) << nLines << endl;
    */

    /* exercise 5
    cout << "Enter a filename: ";
    string filename = "";
    getline(cin, filename);
    cout << "Root: " << getRoot(filename) << endl;
    cout << "Extension: " << getExtension(filename) << endl;
    */

    /* exercise 6
    cout << defaultExtension("Shakespeare", ".txt") << endl;
    cout << defaultExtension("library.h", ".cpp") << endl;
    cout << defaultExtension("library.h", "*.cpp") << endl;
    */

    /* exercise 7
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    string str;
    while (getline(infile, str)) {
        for (int i = 0; i < str.length(); i++) {
            if (isalpha(str[i]) && isupper(str[i])) {
                cout << char(randomInteger('A', 'Z'));
            } else if (isalpha(str[i]) && islower(str[i])) {
                cout << char(randomInteger('a', 'z'));
            } else {
                cout << str[i];
            }
        }
        cout << endl;
    }
    */

    /* exercise 8
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    removeComments(infile, cout);
    */

    /* exercise 9
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    ofstream outfile;
    promptUserForFile(outfile, "Output file: ");
    cout << "Letters to banish: ";
    string banish = "";
    cin >> banish;

    string str;
    while (getline(infile, str)) {
        outfile << removeCharacters(str, banish) << endl;
    }
    */

    /*
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    ofstream outfile;
    promptUserForFile(outfile, "Output file: ");

    string str;
    while (getline(infile, str)) {
        int begin = 0;
        for (int i = 0; i < str.length(); i++) {
            if (str[i] == '\t') {
                outfile << str.substr(begin, i - begin);
                for (int j = 0; j < 8 - (i - begin) % 8; j++)
                    outfile << " ";
                begin = i+1;
            }
        }
        outfile << str.substr(begin, str.length() - begin) << endl;
    }
    */

    /*
    double a = 1.0;
    double b = stringToReal("1.0");
    string c = realToString(a+b);
    cout << c << endl;
    */

    double a = getReal("double: ");
    string str = getLine("line: ");
    cout << a << endl;
    cout << str << endl;

    return 0;
}

/*
 * output
 * exercise 1
 *   theta  |  sin(theta)  |  cos(theta)  |
 *    -90   |  -1.0000000  |   0.0000000  |
 *    -75   |  -0.9659258  |   0.2588190  |
 *    -60   |  -0.8660254  |   0.5000000  |
 *    -45   |  -0.7071068  |   0.7071068  |
 *    -30   |  -0.5000000  |   0.8660254  |
 *    -15   |  -0.2588190  |   0.9659258  |
 *      0   |   0.0000000  |   1.0000000  |
 *     15   |   0.2588190  |   0.9659258  |
 *     30   |   0.5000000  |   0.8660254  |
 *     45   |   0.7071068  |   0.7071068  |
 *     60   |   0.8660254  |   0.5000000  |
 *     75   |   0.9659258  |   0.2588190  |
 *     90   |   1.0000000  |   0.0000000  |
 *
 * exercise 2
 *   36  31  25  19  13   7   1  -5 -11 -16 -22 -28 -34 -40 -46 -52 -57 -63
 *   34  27  21  15   9   3  -4 -10 -16 -22 -28 -35 -41 -47 -53 -59 -66 -72
 *   32  25  19  13   6   0  -7 -13 -19 -26 -32 -39 -45 -51 -58 -64 -71 -77
 *   30  24  17  11   4  -2  -9 -15 -22 -29 -35 -42 -48 -55 -61 -68 -74 -81
 *   29  23  16   9   3  -4 -11 -17 -24 -31 -37 -44 -51 -58 -64 -71 -78 -84
 *   28  22  15   8   1  -5 -12 -19 -26 -33 -39 -46 -53 -60 -67 -73 -80 -87
 *   28  21  14   7   0  -7 -14 -21 -27 -34 -41 -48 -55 -62 -69 -76 -82 -89
 *   27  20  13   6  -1  -8 -15 -22 -29 -36 -43 -50 -57 -64 -71 -78 -84 -91
 *   26  19  12   5  -2  -9 -16 -23 -30 -37 -44 -51 -58 -65 -72 -79 -86 -93
 *   26  19  12   4  -3 -10 -17 -24 -31 -38 -45 -52 -60 -67 -74 -81 -88 -95
 *   25  18  11   4  -3 -11 -18 -25 -32 -39 -46 -54 -61 -68 -75 -82 -89 -97
 *   25  17  10   3  -4 -11 -19 -26 -33 -40 -48 -55 -62 -69 -76 -84 -91 -98
 *
 * exercise 3
 * wangrl.txt
 * Rain is falling all around,
 * It falls on field and tree,
 * It rains on the umbrella here,
 * And on the ships at sea.
 *
 * Input file: wangrl.txt
 * Longest line: It rains on the umbrella here,
 *
 * exercise 4
 * Input file: Lear.txt
 * Chars: 254
 * Words:  43
 * Lines:   6
 *
 * exercise 5
 * Enter a filename: hello.txt
 * Root: hello
 * Extension: txt
 *
 * exercise 6
 * Shakespeare.txt
 * library.h
 * library.cpp
 *
 * exercise 7
 * Input file: Troilus.txt
 * Xy, Kwpxp; ypb askx zvhpw ld pekosgfw ftue
 * Er uchsrisksq jo yzl jc Aomo gtu dzoyd
 * Spyuxqlf jvyz Fmxex:
 *
 * exercise 8
 * program.txt
 * Input file: program.txt

 * #include 
 * using namespace std;
 *
 * int main() {
 *    int a, b, c;
 *    b = 1; c = 2;
 *
 *    a = a + b;
 *    cout << a << endl;
 *    return 0;
 * }
 *
 * exercise 9
 * Input file: TheWonderfulO.txt
 * Output file: TheWnderful.txt
 * Letters to banish: aeiou
 *
 * Smwhr  pndrs twr clck slwly
 * drppd  dzn strks nt th glm.
 * Strm clds rd lw lng th hrzn,
 * nd n mn shwn.  Only  mlnchly
 * chrs f frgs brk th sndlssnss.
 *
 * exercise 10
 * success
 * Input file: tableindent.txt
 * Output file: backspace.txt
 * abc     pqrst   xyz
 * abcd    lmn     uv
 *
 * exercise 11
 * 2
 *
 * exercise 12
 * double: 1.0
 * line: wang rl
 * 1
 * wang rl
 */
#include 
#include 
#include "console.h"
#include "filelib.h"
#include "vector.h"
#include 
using namespace std;


int main() {

    /* vector
    ifstream infile;
    Vector lines;
    promptUserForFile(infile, "Input file: ");
    readEntireFile(infile, lines);
    infile.close();
    for (int i = lines.size() - 1; i >= 0; i--) {
        cout << lines[i] << endl;
    }
    */
    
    /*
    Vector letterCounts(26);
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    char ch;
    while(infile.get(ch)) {
        if (isalpha(ch)) {
            letterCounts[toupper(ch)-'A']++;
        }
    }
    infile.close();
    for (char ch = 'A'; ch <= 'Z'; ch++) {
        if (letterCounts[ch-'A'] != 0)
        cout << setw(7) << letterCounts[ch-'A'] << " " << ch << endl;
    }
    */

    return 0;
}

/*
 * output
 * Input file: wangrl.txt
 * And on the ships at sea.
 * It rains on the umbrella here,
 * It falls on field and tree,
 * Rain is falling all around,
 * 
 * Input file: wangrl.txt
 *    11 A
 *     1 B
 *     4 D
 *     9 E
 *     3 F
 *     1 G
 *     4 H
 *     8 I
 *     9 L
 *     1 M
 *     9 N
 *     4 O
 *     1 P
 *     6 R
 *     6 S
 *     6 T
 *     2 U     
 */

Set类的解释

The Set class is used to model the mathematical abstraction of a set, which is a collection in which the elements are unordered and in which each value appears only once.

/*
 * This program simulates a checkout line, such as one you
 * might encounter in a grocery store. Customers arrive at
 * the checkout stand and get in line.
 */

#include 
#include 
#include "queue.h"
#include 
#include "map.h"
#include "console.h"
#include "strlib.h"
#include "random.h"
#include "lexicon.h"
#include "filelib.h"
using namespace std;

const double ARRIVAL_PROBABILITY = 0.05;
const int MIN_SERVICE_TIME = 5;
const int MAX_SERVICE_TIME = 15;
const int SIMULATION_TIME = 2000;

void runsimulation(int &nServed, int &totalWait, int &totalLength) {
    Queue queue;
    int timeRemaining = 0;
    nServed = 0;
    totalWait = 0;
    totalLength = 0;
    for (int t = 0; t < SIMULATION_TIME; t++) {
        if (randomChance(ARRIVAL_PROBABILITY)) {
            queue.enqueue(t);
        }
        if (timeRemaining > 0) {
            timeRemaining--;
        } else if (!queue.isEmpty()) {
            totalWait += t - queue.dequeue();
            nServed++;
            timeRemaining = randomInteger(MIN_SERVICE_TIME, MAX_SERVICE_TIME);
        }
        totalLength += queue.size();
    }
}

void printReport(int nServed, int totalWait, int totalLength) {
    cout << "Simulation results given the following constants:" << endl;
    cout << "Customers served:      " << setw(4) << nServed << endl;
    cout << "Average waiting time:  " << setw(7) << double(totalWait) / nServed << endl;
    cout << "Average queue length:  " << setw(7) << double(totalLength) / SIMULATION_TIME << endl;
}

void readCodeFile(string filename, Map &map) {
    ifstream infile;
    infile.open(filename.c_str());
    if (infile.fail()) error("Can't read the data file");
    string line;
    while (getline(infile, line)) {
        if (line.length() < 4 || line[3] != '=') {
            error("Illegal data line: " + line);
        }
        string code = toUpperCase(line.substr(0, 3));
        map.put(code, line.substr(4));
    }
    infile.close();
}

string wordToPigLatin(string word);
int findFirstVowel(string word);
bool isVowel(char ch);

void countWords(istream &stream, Map &wordCounts);
void displayWordCounts(Map & wordCounts);
void extractWords(string line, Vector &words);


int main() {
    /*
    int nServed;
    int totalWait;
    int totalLength;
    runsimulation(nServed, totalWait, totalLength);
    printReport(nServed, totalWait, totalLength);
    */

    /*
    Map airportCodes;
    readCodeFile("AirportCodes.txt", airportCodes);
    while (true) {
        string line;
        cout << "Airport code: ";
        getline(cin, line);
        if (line == "") break;
        string code = toUpperCase(line);
        if (airportCodes.containsKey(code)) {
            cout << code << " is in " << airportCodes.get(code) << endl;
        } else {
            cout << "There is no such airport code" << endl;
        }
    }
    */

    /*
     * not binary file, it can't open.
     * every word only occur just once.
     */
    /*
    Lexicon english("EnglishWords.dat");
    string word = "xx";
    for (char c0 = 'a'; c0 <= 'z'; c0++) {
        word[0] = c0;
        for (char c1 = 'a'; c1 <= 'z'; c1++) {
            word[1] = c1;
            if (english.contains(word)) {
                cout << word << endl;
            }
        }
    }
    */

    /*
    cout << "This program finds words that remain words"
         << " when translated to Pig Latin." << endl;
    Lexicon english("EnglishWords.dat");
    for (string word : english) {
        string pig = wordToPigLatin(word);
        if (pig != word && english.contains(pig)) {
            cout << word << " -> " << pig << endl;
        }
    }
    */

    ifstream infile;
    Map wordCounts;
    promptUserForFile(infile, "Input file: ");
    countWords(infile, wordCounts);
    infile.close();
    displayWordCounts(wordCounts);

    return 0;
}

void countWords(istream &stream, Map &wordCounts) {
    Vector lines, words;
    readEntireFile(stream, lines);
    for (string line : lines) {
        extractWords(line, words);
        for (string word : words) {
            wordCounts[toLowerCase(word)]++;
        }
    }
}

void displayWordCounts(Map &wordCounts) {
    for (string word : wordCounts) {
        cout << left << setw(15) << word
             << right << setw(5) << wordCounts[word] << endl;
    }
}

void extractWords(string line, Vector &words) {
    words.clear();
    int start = -1;
    for (int i = 0; i < line.length(); i++) {
        if (isalpha(line[i])) {
            if (start == -1) start = i;
        } else {
            if (start >= 0) {
                words.add(line.substr(start, i - start));
                start = -1;
            }
        }
    }
    if (start >= 0) words.add(line.substr(start));
}

bool isVowel(char ch) {
    switch(ch) {
    case 'A': case 'E': case 'I': case 'O': case 'U':
    case 'a': case 'e': case 'i': case 'o': case 'u':
        return true;
    default:
        return false;
    }
}

int findFirstVowel(string word) {
    for (int i = 0; i < word.length(); i++) {
        if (isVowel(word[i])) return i;
    }
    return -1;
}

string wordToPigLatin(string word) {
    int vp = findFirstVowel(word);
    if (vp == -1) {
        return word;
    } else if (vp == 0) {
        return word + "way";
    } else {
        string head = word.substr(0, vp);
        string tail = word.substr(vp);
        return tail + head + "ay";
    }
}

/*
 * output
 * Simulation results given the following constants:
 * Customers served:       110
 * Average waiting time:  7.30909
 * Average queue length:    0.405
 *
 * output
 * Airport code: LHR
 * LHR is in London, England, United Kingdom
 * Airport code: SFO
 * SFO is in San Francisco, CA, USA
 * Airport code: XXX
 * There is no such airport code
 * Airport code:
 *
 * output
 * ak
 * cv
 * fo
 * ha
 * sf
 *
 * output
 * This program finds words that remain words when translated to Pig Latin.
 * fejif -> ejiffay
 * ffe -> effay
 *
 * output
 * Input file: Macbeth.txt
 * and                2
 * creeps             1
 * day                2
 * from               1
 * in                 1
 * pace               1
 * petty              1
 * this               1
 * to                 1
 * tomorrow           3
 *
 */

#include 
#include "vector.h"
#include "filelib.h"
#include "console.h"
#include "math.h"

using namespace std;
void readVector(istream &is, Vector &vec) {
    string str;
    while (getline(is, str)) {
        if (str == "") return;
        double i = stringToDouble(str);
        vec.push_back(i);
    }
}

void readVector(istream &is, Vector &vec) {
    string str;
    while (getline(is, str)) {
        if (str == "") return;
        int i = stringToInteger(str);
        vec.push_back(i);
    }
}

void readVector(istream &is, Vector &vec) {
    string str;
    while (getline(is, str)) {
        if (str == "") return;
        vec.push_back(str);
    }
}

double mean(Vector &data) {
    double total = 0;
    for (double d : data) {
        total += d;
    }
    return total/data.size();
}

double stddev(Vector &data) {
    double meanX = mean(data);
    double total = 0;
    for (int i = 0; i < data.size(); i++) {
        total += (meanX - data[i]) * (meanX -data[i]);
    }
    return sqrt(total/data.size());
}

int main() {
    /*
    Vector vec;
    ifstream infile;
    promptUserForFile(infile, "Input file: ");

    readVector(infile, vec);
    cout << vec << endl;
    vec.clear();
    readVector(infile, vec);
    cout << vec << endl;
    vec.clear();
    readVector(infile, vec);
     cout << vec << endl;
     */

    /* exercise 2
     Vector data = {1.0, 2.0, 3.0};
     cout << mean(data) << endl;
    */

    /* exercise 3
    Vector data = {1.0, 2.0, 3.0};
    cout << stddev(data) << endl;
    */
    
    /*
    Vector scores(11);
    ifstream infile;
    string str;
    promptUserForFile(infile, "Input file: ");
    while (getline(infile, str)) {
        if (str == "") break;
        int score = stringToInteger(str);
        scores[score/10]++;
    }

    for (int i = 0; i <= 10; i++) {
        cout << i * 10;
          if (i != 10) cout << "s";
          cout << ": ";
        for (int j = 0; j < scores[i]; j++)
            cout << '*' ;
        cout << endl;
    }
    */
    
    
    return 0;
}

/*
 * output
 * exercise 1
 * Input file: SquareAndCubeRoots.txt
 * {1, 1.4142, 1.7321, 2}
 * {1, 1.2599, 1.4422, 1.5874, 1.71, 1.8171, 1.9129, 2}
 * {}
 *
 * exercise 2
 * 2
 *
 * exercise 3
 * 0.816497
 *
 * exercise 4
 * Input file: data.txt
 * 0s: 
 * 10s: 
 * 20s: 
 * 30s: 
 * 40s: *
 * 50s: *
 * 60s: 
 * 70s: **
 * 80s: *****
 * 90s: **
 * 100: *
 */

这个hist.h和hist.cpp不知道怎么写。

#ifndef HIST_H
#define HIST_H
int setMinVaule(int &value);
int setMaxValue(int &value);
int setRange(int &value);
#endif // HIST_H

#include "hist.h"
int setMinVaule(int &value)
{
    return value;
}

int setMaxValue(int &value)
{
    return value;
}

int setRange(int &value)
{
    return value;
}
#include 
#include "vector.h"
#include "console.h"
#include "fstream"
#include "grid.h"
#include "queue.h"
#include "stack.h"
#include "error.h"
using namespace std;
void fillGrid(Grid &grid, Vector &values) {
    if (grid.size() != values.size()) return;
    for (int i = 0; i < grid.numRows(); i++) {
        for (int j = 0; j < grid.numCols(); j++) {
            grid[i][j] = values[i*grid.numCols()+j];
        }
    }
}
bool isMagicSquare(Grid &square) {
    int row = square.numRows();
    int col = square.numCols();
    if (col != row) return false;
    int sum = 0;
    for (int i = 0; i < row; i++) {
        sum += square[0][i];
    }
    // rows
    for (int i = 0; i < row; i++) {
        int sum1 = 0;
        for (int j = 0; j < col; j++) {
            sum1 += square[i][j];
        }
        if (sum != sum1) return false;
    }
    // columns
    for (int i = 0; i < row; i++) {
        int sum1 = 0;
        for (int j = 0; j < col; j++) {
            sum1 += square[j][i];
        }
        if (sum != sum1) return false;
    }
    // diagonals
    int sum2 = 0;
    int sum3 = 0;
    for (int i = 0; i < row; i++) {
        sum2 += square[i][i];
        sum3 += square[col-i-1][i];
    }
    if (sum2 != sum || sum3 != sum) return  false;
    return true;
}
bool checkSudokuSolution(Grid &puzzle) {
    int sum = 0;
    for (int i = 1; i <= 9; i++) {
        sum += i;
    }
    for (int i = 0; i < 9; i++) {
        int sum1 = 0;
        for (int j = 0; j < 9; j++) {
            sum1 += puzzle[i][j];
        }
        if (sum != sum1) return false;
    }
    for (int i = 0; i < 9; i++) {
        int sum1 = 0;
        for (int j = 0; j < 9; j++) {
            sum1 += puzzle[j][i];
        }
        if (sum != sum1) return false;
    }
    return true;
}

void fixCounts(Grid &mines, Grid &counts) {
    /* hard method
    int row = mines.numRows();
    int col = mines.numCols();
    // four angles
    counts[0][0] = mines[0][0] + mines[0][1] + mines[1][0] + mines[1][1];
    counts[0][col-1] = mines[0][col-1] + mines[0][col-2] + mines[1][col-2] + mines[1][col-1];
    counts[row-1][0] = mines[row-1][0] + mines[row-1][1] + mines[row-2][0] + mines[row-2][1];
    counts[row-1][col-1] = mines[row-1][col-1] + mines[row-1][col-2] + mines[row-1][col-2] + mines[row-1][col-1];
    */

    for (int i = 1; i < mines.numRows() -1; i++) {
        for (int j = 1; j < mines.numCols() - 1; j++) {
            counts[i-1][j-1] = mines[i-1][j-1]+mines[i-1][j]+mines[i-1][j+1]
                            +mines[i][j-1]+mines[i][j]+mines[i][j+1]
                            +mines[i+1][j-1]+mines[i+1][j]+mines[i+1][j+1];
        }
    }
}
void reshape(Grid &grid, int nRows, int nCols) {
    int row = grid.numRows();
    int col = grid.numCols();
    Queue que;
    for (int i = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            que.enqueue(grid[i][j]);
        }
    }
    Grid sgrid(nRows, nCols);
    for (int i = 0; i < nRows; i++) {
        for (int j = 0; j < nCols; j++) {
            sgrid[i][j] = que.dequeue();
        }
    }
    grid = sgrid;
}
void reverseQueue(Queue &queue) {
    Stack vec;
    while (!queue.isEmpty()) {
        vec.push(queue.dequeue());
    }
    while (!vec.isEmpty()) {
        queue.enqueue(vec.pop());
    }
}
bool checkBracket(string str) {
    Stack brackets;
    for (int i = 0; i < str.length(); i++) {
        switch (str[i]) {
        case '(':
            brackets.push('(');
            break;
        case '[':
            brackets.push('[');
            break;
        case '{':
            brackets.push('{');
            break;
        case ')':
            if (brackets.isEmpty() || brackets.pop() != '(') return false;
            break;
        case ']':
            if (brackets.isEmpty() || brackets.pop() != '[') return false;
            break;
        case '}':
            if (brackets.isEmpty() || brackets.pop() != '}') return false;
            break;
        }
    }
    if (!brackets.isEmpty()) return false;
    return true;
}
int main() {
    /* exercise 6
    Vector vec;
    for (int i = 0; i <= 1000; i++) {
        vec.add(i);
    }

    for (int i = 2; i <= 1000; i++) {
        int range = 2;
        while (i * range <= 1000) {
            vec[i*range] = 0;
            range++;
        }
    }
    for (int i = 2; i <= 1000; i++) {
        if (vec[i] != 0) cout << vec[i] << " ";
    }
    cout << endl;
    */

    /* exercise 7
    Grid matrix(3, 3);
    Vector values;
    values += 1, 2, 3;
    values += 4, 5, 6;
    values += 7, 8, 9;
    fillGrid(matrix, values);
    cout << matrix << endl;
    */

    /* exercise 8
    Grid grid = {{8, 1, 6}, {3, 5, 7}, {4, 9 ,2}};
    cout << isMagicSquare(grid) << endl;
    */

    /* exercise 9
    Grid sudoku = {{3, 9, 2, 4, 6, 5, 8, 1, 7},
                        {7, 4, 1, 8, 9, 3, 6, 2, 5},
                        {6, 8, 5, 2, 7, 1, 4, 3, 9},
                        {2, 5, 4, 1, 3, 8, 7, 9, 6},
                        {8, 3, 9, 6, 2, 7, 1, 5, 4},
                        {1, 7, 6, 9, 5, 4, 2, 8, 3},
                        {9, 6, 7, 5, 8 ,2, 3, 4, 1},
                        {4, 2, 3, 7, 1, 9, 5, 6, 8},
                        {5, 1, 8, 3, 4, 6, 9, 7, 2}};
    cout << checkSudokuSolution(sudoku) << endl;
    */

    /* exercise 10
    Grid mineCounts(6,6);
    Grid mineLocations = {{0, 0, 0, 0, 0, 0, 0, 0},
                                {0, 1, 0, 0, 0, 0, 1, 0},{0, 0, 0, 0, 0, 0, 1,0},
                               {0, 1, 1, 0, 1, 0, 1, 0},{0, 1, 0, 0, 0, 0, 0, 0},
                               {0, 0, 0, 1, 0, 0, 0, 0},{0, 0, 0, 0, 0, 0, 0, 0},
                               {0, 0, 0, 0, 0, 0, 0, 0}};
    fixCounts(mineLocations, mineCounts);

    cout << mineCounts << endl;
    */

    /* exercise 11
    Grid myGrid = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
    reshape(myGrid, 4, 3);
    cout << myGrid << endl;
    reshape(myGrid,2, 5);
    cout << myGrid << endl;
    */

    /* exercise 12
    Stack st;
    cout << "Enter a list of integers, ending with 0" << endl;
    int number;
    do {
        cout << "? ";
        cin >> number;
        if (number != 0) st.push(number);
    } while (number != 0);

    cout << "Those integers in reverse order are: " << endl;
    while (!st.isEmpty())
        cout << " " << st.pop() << endl;
    */

    /* exercise 13
    Queue queue = {"wang", "rl"};
    reverseQueue(queue);
    cout << queue << endl;
    */

    /* exercise 14
    cout << checkBracket("(([])") << endl;
    cout << checkBracket(")(") << endl;
    cout << checkBracket("{(})") << endl;
    cout << checkBracket("()") << endl;
    */

    
    return 0;
}

/*
 * output
 * exercise 6
 * 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59
 * 61 67 71 73 79 83 89 97 101 103 107 109 113 127
 * 131 137 139 149 151 157 163 167 173 179 181 191
 * 193 197 199 211 223 227 229 233 239 241 251 257
 * 263 269 271 277 281 283 293 307 311 313 317 331
 * 337 347 349 353 359 367 373 379 383 389 397 401
 * 409 419 421 431 433 439 443 449 457 461 463 467
 * 479 487 491 499 503 509 521 523 541 547 557 563
 * 569 571 577 587 593 599 601 607 613 617 619 631
 * 641 643 647 653 659 661 673 677 683 691 701 709
 * 719 727 733 739 743 751 757 761 769 773 787 797
 * 809 811 821 823 827 829 839 853 857 859 863 877
 * 881 883 887 907 911 919 929 937 941 947 953 967
 * 971 977 983 991 997
 *
 * exercise 7
 * {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
 *
 * exercise 8
 * 1
 *
 * exercise 9
 * 1
 *
 * exercise 10
 * {{1, 1, 0, 0, 2, 2}, {3, 3, 2, 1, 4, 3}, {3, 3, 2, 1, 3, 2},
 * {3, 4, 3, 2, 2, 1}, {1, 2, 1, 1, 0, 0}, {0, 1, 1, 1, 0, 0}}
 *
 * exercise 11
 * {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}}
 * {{1, 2, 3, 4, 5}, {6, 7, 8, 9, 10}}
 *
 * exercise 12
 * Enter a list of integers, ending with 0
 * ? 10
 * ? 20
 * ? 30
 * ? 40
 * ? 0
 * Those integers in reverse order are:
 *  40
 *  30
 *  20
 *  10
 *
 * exercise 13
 * {"rl", "wang"}
 *
 * exercise 14
 * 0
 * 0
 * 0
 * 1
 */
#include 
#include "vector.h"
#include "filelib.h"
#include "console.h"
#include "math.h"
#include "stack.h"
#include "queue.h"
#include 
using namespace std;

void roll(Stack &stack, int n, int k) {
    Stack tempStack;
    for (int i = 0; i < k; i++) {
        tempStack.push(stack.pop());
    }
    Stack temp2Stack;
    for (int j = 0; j < n-k; j++ ) {
        temp2Stack.push(stack.pop());
    }
    while (!tempStack.isEmpty()) {
        stack.push(tempStack.pop());
    }
    while (!temp2Stack.isEmpty()) {
        stack.push(temp2Stack.pop());
    }
}

const double ARRIVAL_PROBABILITY = 0.4;
const int MIN_SERVICE_TIME = 5;
const int MAX_SERVICE_TIME = 15;
const int SIMULATION_TIME = 2000;

int smallestElement(Vector> &queue) {
    int smallest = queue[0].size();
    int smallindex = 0;
    for (int i = 0; i < queue.size(); i++) {
        if (queue[i].size() < smallest) {
            smallest = queue[i].size();
            smallindex = i;
        }
    }
    return smallindex;
}

void runsimulation(int &nServed, int &totalWait, int &totalLength) {
    Vector > queue(5);
    Vector timeRemaining(2);
    nServed = 0;
    totalWait = 0;
    totalLength = 0;

    for (int t = 0; t < SIMULATION_TIME; t++) {
        if (randomChance(ARRIVAL_PROBABILITY)) {
            int i = smallestElement(queue);
            queue[i].enqueue(t);
        }
        for (int i = 0; i  < queue.size(); i++) {
            for (int j = 0; j < timeRemaining.size(); j++) {
                if (timeRemaining[j] > 0) {
                     timeRemaining[j]--;
                } else if (!queue[i].isEmpty()) {
                    totalWait += t - queue[i].dequeue();
                    nServed++;
                     timeRemaining[j] = randomInteger(MIN_SERVICE_TIME, MAX_SERVICE_TIME);
                }
            }
            totalLength += queue[i].size();
        }
    }
}

void printReport(int nServed, int totalWait, int totalLength) {
    cout << "Simulation results given the following constants:" << endl;
    cout << "Customers served:      " << setw(4) << nServed << endl;
    cout << "Average waiting time:  " << setw(7) << double(totalWait) / nServed << endl;
    cout << "Average queue length:  " << setw(7) << double(totalLength) / SIMULATION_TIME << endl;
}

using namespace std;
int main() {
    /*
    Stack stack = {'A', 'B', 'C', 'D'};
    roll(stack, 4, 1);
    cout << stack << endl;
    Stack stack1 = {'A', 'B', 'C', 'D'};
    roll(stack1, 3, 2);
    cout << stack1 << endl;
    Stack stack2 = {'A', 'B', 'C', 'D'};
    roll(stack2, 2, 4);
    cout << stack2 << endl;
    */

    int nServed;
    int totalWait;
    int totalLength;
    runsimulation(nServed, totalWait, totalLength);
    printReport(nServed, totalWait, totalLength);
    return 0;
}

/*
 * output
 * exercise 15
 * {D, A, B, C}
 * {A, C, D, B}
 * {A, B, C, D}
 *
 * exercise 16
 * Simulation results given the following constants:
 * Customers served:       790
 * Average waiting time:  6.18354
 * Average queue length:   2.4435
 *
 * exercise 17
 * Simulation results given the following constants:
 * Customers served:       803
 * Average waiting time:  0.139477
 * Average queue length:    0.056
 */
#include 
using namespace std;
#include "grid.h"
#include "console.h"
#include "random.h"
#include 
#include "filelib.h"
#include "map.h"
#include "lexicon.h"
#include 
#include 
#include 
void runsimulation(int &totalTime, int &maximumBall, int &trapsSprung) {
    Grid mousetraps(8, 8, true);
    int ballsAir = 1;
    maximumBall = 0;
    totalTime = 0;
    trapsSprung = 0;
    while (ballsAir != 0) {
        int i = randomInteger(0, 7);
        int j = randomInteger(0, 7);
        ballsAir--;
        totalTime++;
        if (mousetraps[i][j]) {
            mousetraps[i][j] = false;
            ballsAir += 2;
        }
        if (ballsAir > maximumBall) maximumBall = ballsAir;
    }
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            if (!mousetraps[i][j]) trapsSprung++;
        }
    }
}

void printReport(int totalTime, int maximumBall, int trapsSprung) {
    cout << "Time units have elapsed since the beginning: " << totalTime << endl;
    cout << "Percentage of the traps have been sprung: " << trapsSprung/64.0 << endl;
    cout << "Maximum number of balls in the air: " << maximumBall << endl;
}

string letterToMorse(char c) {
    switch(c) {
    case 'A':   return ".-";
    case 'B':   return "-...";
    case 'C':   return "-.-.";
    case 'D':   return "-..";
    case 'E':   return ".";
    case 'F':   return "..-.";
    case 'G':   return "--.";
    case 'H':   return "....";
    case 'I':   return "..";
    case 'J':   return ".---";
    case 'K':   return "-.-";
    case 'L':   return ".-..";
    case 'M':   return "--";
    case 'N':   return "-.";
    case 'O':   return "---";
    case 'P':   return ".--.";
    case 'Q':   return "--.-";
    case 'R':   return ".-.";
    case 'S':   return "...";
    case 'T':   return "-";
    case 'U':   return "..-";
    case 'V':   return "...-";
    case 'W':   return ".--";
    case 'X':   return "-..-";
    case 'Y':   return "-.--";
    case 'Z':   return "--..";

    }
}

void makeMap(map &map) {
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    string str;
    while (getline(infile, str)) {
        if (str == "") return;
        int number = stringToInteger(str.substr(0, 3));
        string district = str.substr(4);
        map.insert(make_pair(number, district));
    }
}

void lookup(map map1) {
    cout << "Enter area code or state name: ";
    string str;
    while (getline(cin, str)) {
        if (str == "") return;
        else if (isupper(str[0])) {
            map::iterator iter;
            iter = map1.begin();
            while (iter != map1.end()) {
                if (str == iter->second) {
                    cout << iter->first << endl;
                }
                iter++;
            }
            cout << "Enter area code or state name: ";
        } else {
            int number = stringToInteger(str);
            cout << map1[number] << endl;
            cout << "Enter area code or state name: ";
        }
    }
}
void makeVectorMap(map> &map2) {
    ifstream infile;
    promptUserForFile(infile, "Input file: ");
    string str;

    while (getline(infile, str)) {
        if (str == "") return;
        int number = stringToInteger(str.substr(0, 3));
        string district = str.substr(4);
        map>::iterator iter;
        iter = map2.begin();
        while (iter != map2.end()) {
             if (iter->first == district) {
                 iter->second.push_back(number);
                 iter++;
                 continue;
             }
             iter++;
        }
        vector vecNumber;
        vecNumber.push_back(number);
        map2.insert(make_pair(district, vecNumber));
    }
    cin.clear();
}
void findAreaCode(map> map2) {
    cout << "Enter area code or state name: ";
    string str;
    while (getline(cin, str)) {
        if (str == "") return;
        map>::iterator iter;
        iter = map2.begin();
        while (iter != map2.end()) {
            if (iter->first == str) {
                for (int i = 0; i < (iter->second).size(); i++) {
                   cout <<  (iter->second)[i] << endl;
                }
            }
            iter++;
        }
        cout << "Enter area code or state name: ";
    }
}

bool isPalindrome(string str) {
    int n = str.length();
    for (int i = 0; i < n/2; i++) {
        if (str[i] != str[n-i-1]) return false;
    }
    return true;
}

int main() {

    /* exercise 18
    int totalTime = 0;
    int maximumBall = 0;
    int trapsSprung = 0;
    runsimulation(totalTime, maximumBall, trapsSprung);
    printReport(totalTime, maximumBall, trapsSprung);
    */

    /* exercise 19
    cout << "Morse code translator" << endl;
    string str;
    cout << "> ";
    while (getline(cin, str)) {
        for (int i = 0; i < str.length(); i++) {
            if (isupper(str[i]))
                cout << letterToMorse(str[i]) << " ";
        }
        cout << "\n>";
    }
    */

    /* exercise 20
    map map;
    makeMap(map);
    lookup(map);
    */

    /* exercise 21
    map> map2;
    makeVectorMap(map2);
    findAreaCode(map2);
    */

    /* exercise 22
    Lexicon english("palindrome.dat");
    for (string word : english) {
        if (isPalindrome(word))
            cout << word << endl;
    }
    */

    /* exercise 23
    Lexicon english("EnglishWords.dat");
    string word = "xx";
    for (char c0 = 'a'; c0 <= 'z'; c0++) {
        word[0] = c0;
        for (char c1 = 'a'; c1 <= 'z'; c1++) {
            word[1] = c1;
            if (english.contains(word)) {
                cout << "a" << word << "  ";
                cout << word << "a" << endl;
            }
        }
    }
    */

    /* exercise 24
    Lexicon english("EnglishWords.dat");
    string word = "xx";
    for (char c0 = 'a'; c0 <= 'z'; c0++) {
        word[0] = c0;
        for (char c1 = 'a'; c1 <= 'z'; c1++) {
            word[1] = c1;
            if (english.contains(word)) {
                cout << word << "s" << endl;
            }
        }
    }
    */
    Lexicon english("EnglishWords.dat");
    Vector lengths(50);
    for (string word : english) {
        lengths[word.length()]++;
    }
    for (int i =0 ; i < lengths.size(); i++) {
        if (lengths[i] != 0) {
            cout < SOS TITANIC
 * ... --- ... - .. - .- -. .. -.-.
 * >WE ARE SINKING FAST
 * .-- . .- .-. . ... .. -. -.- .. -. --. ..-. .- ... -
 * >
 *
 * exercise 20
 * Input file: AreaCodes.txt
 * Enter area code or state name: 650
 * California
 * Enter area code or state name: 202
 * District of Columbia
 * Enter area code or state name: 778
 * British Columbia
 * Enter area code or state name: Oregon
 * 458
 * 503
 * 541
 * 971
 * Enter area code or state name: Manitoba
 * 204
 * Enter area code or state name:
 *
 * exercise 21
 * Input file: AreaCodes.txt
 * Enter area code or state name: Oregon
 * 458
 * 503
 * 541
 * 971
 * Enter area code or state name:
 *
 * exercise 22
 * wfjfw
 * wrw
 *
 * exercise 23
 * aak  aka
 * acv  cva
 * afo  foa
 * aha  haa
 * asf  sfa
 *
 * exercise 24
 * aks
 * cvs
 * fos
 * has
 * sfs
 * 
 * exercise 25
 *  1        1
 *  2        5
 *  3        4
 *  4        5
 *  5        8
 *  6        1
 *  7        4
 * 11        1
 */


第六章 习题集

6.1 Representing points

6.2 Operator overloading

6.3 Rational numbers

6.4 Designing a token scanner class

6.5 Encapsulating programs as classes

主要讲如何写类,操作符的重载,设计类的建议。

1. 对象,结构,类,成员变量,方法
2. public表示外部对象可以访问,private不能访问
3. false
4. .
5. classname
6. 0
7. 获取成员变量,设置成员变量
8. 不可变量
9. ClassName::
10. private
11. perator%
12. prefix先改变变量再做计算
13. 可以连续使用
14. true
15. method-based这个类可以调用,free-function适用更多类
16. friend可以访问内部private变量
17. 更改方向
18. 5步
19. 分数
20. den != 0
21. no
22. 两个字符算术计算
23. 字符集
24. while(){}
25. TokenScanner token = new TokenScanner();
26. 适用类的方式进行编程

#include 
#include "domino.h"
#include "card.h"

using namespace std;

int main(int argc, char *argv[])
{
    /* exercise 1
    for (int i = 0; i <= 6; i++) {
        for (int j = 0; j <=i; j++) {
            Domino domino(i, j);
            cout << domino << " ";
        }
        cout << endl;
    }
    */

    for (Suit suit = CLUBS; suit <= SPADES; suit++) {
        for (int rank = ACE; rank <= KING; rank++) {
            cout << " " << Card(rank, suit);
        }
        cout << endl;
    }
    return 0;
}

/*
 * output
 * exercise 1
 * (0-0)
 * (1-0) (1-1)
 * (2-0) (2-1) (2-2)
 * (3-0) (3-1) (3-2) (3-3)
 * (4-0) (4-1) (4-2) (4-3) (4-4)
 * (5-0) (5-1) (5-2) (5-3) (5-4) (5-5)
 * (6-0) (6-1) (6-2) (6-3) (6-4) (6-5) (6-6)
 *
 * exercise 2
 *  AC 2C 3C 4C 5C 6C 7C 8C 9C 10C JC QC KC
 *  AD 2D 3D 4D 5D 6D 7D 8D 9D 10D JD QD KD
 *  AH 2H 3H 4H 5H 6H 7H 8H 9H 10H JH QH KH
 *  AS 2S 3S 4S 5S 6S 7S 8S 9S 10S JS QS KS
 *
 * exercise 3
 * write GPoint & GRectangle class
 *
 */
exercise 4 愚蠢的写法

#include 
#include "domino.h"
#include "card.h"

using namespace std;

int main(int argc, char *argv[])
{
    /* exercise 1
    for (int i = 0; i <= 6; i++) {
        for (int j = 0; j <=i; j++) {
            Domino domino(i, j);
            cout << domino << " ";
        }
        cout << endl;
    }
    */

    for (Suit suit = CLUBS; suit <= SPADES; suit++) {
        for (int rank = ACE; rank <= KING; rank++) {
            cout << " " << Card(rank, suit);
        }
        cout << endl;
    }
    return 0;
}

/*
 * output
 * exercise 1
 * (0-0)
 * (1-0) (1-1)
 * (2-0) (2-1) (2-2)
 * (3-0) (3-1) (3-2) (3-3)
 * (4-0) (4-1) (4-2) (4-3) (4-4)
 * (5-0) (5-1) (5-2) (5-3) (5-4) (5-5)
 * (6-0) (6-1) (6-2) (6-3) (6-4) (6-5) (6-6)
 *
 * exercise 2
 *  AC 2C 3C 4C 5C 6C 7C 8C 9C 10C JC QC KC
 *  AD 2D 3D 4D 5D 6D 7D 8D 9D 10D JD QD KD
 *  AH 2H 3H 4H 5H 6H 7H 8H 9H 10H JH QH KH
 *  AS 2S 3S 4S 5S 6S 7S 8S 9S 10S JS QS KS
 *
 * exercise 3
 * write GPoint & GRectangle class
 *
 */

exercise 4 聪明的写法,应该还漏掉几个空

#include 
#include 
using namespace std;
#include "console.h"
#include "vector.h"
#include "gtypes.h"
const int N_ACROSS = 50;
const int N_DOWN = 30;
const int DELTA = 670;
int main() {
    GWindow gw;
    Vector  points;
    int length = 0;
    for (int i = 0; i <= N_ACROSS; i++) {
        points.push_back(GPoint(i*10, 0));
    }
    for (int j = 0; j <= N_DOWN; j++) {
        points.push_back(GPoint(N_ACROSS*10, j * 10));
    }
    for (int i = (N_ACROSS-1); i >= 0; i--) {
        points.push_back(GPoint(i*10, N_DOWN*10));
    }
    for (int j = (N_DOWN-1); j >= 0; j--) {
        points.push_back(GPoint(0, j*10));
    }
    while (true) {
        length += DELTA;
        length %= 1600;
        if (length == 0) break;
        gw.drawLine(points[(length+1600-DELTA)%1600/10],points[length/10]);
    }
    return 0;
}
#ifndef CALENDAR_H
#define CALENDAR_H
#include 
#include "strlib.h"
#include 

enum Month {
    JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST,
    SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER
};

int daysInMonth(Month month, int year);
bool isLeapYear(int year);
std::string monthToString(Month month);

class Date {
public:
    Date();
    Date(Month month, int day, int year);
    Date(int day, Month month, int year);

    int getDay();
    Month getMonth();
    int getYear();
    std::string toString() const;

    bool operator==(const Date & date2) const;
    bool operator!=(const Date & date2) const;
    bool operator<=(const Date & date2) const;
    bool operator<(const Date & date2) const;

    Date operator+(const int day);
    int operator-(const Date &date2);
    friend Date operator++(Date & date, int);
private:
    int day;
    Month month;
    int year;

};

Date operator++(Date & date, int);
std::ostream & operator<<(std::ostream &os, const Date &date);

#endif // CALENDAR_H
#include "calendar.h"
#include 
#include 
#include 
#include 

int daysInMonth(Month month, int year)
{
    switch (month) {
    case 0:
        return 31;
    case 1:
        if (isLeapYear(year))
            return 29;
        else
            return 28;
    case 2:
        return 31;
    case 3:
        return 30;
    case 4:
        return 31;
    case 5:
        return 30;
    case 6:
        return 31;
    case 7:
        return 31;
    case 8:
        return 30;
    case 9:
        return 31;
    case 10:
        return 30;
    case 11:
        return 31;
    default:
        std::cout << "invalid month.";
    }
}

bool isLeapYear(int year)
{
    return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}

std::string monthToString(Month month)
{
    switch (month) {
    case 0:
        return "JAN";
    case 1:
        return "FEB";
    case 2:
        return "MAR";
    case 3:
        return "APR";
    case 4:
        return "MAY";
    case 5:
        return "JUN";
    case 6:
        return "JUL";
    case 7:
        return "AUG";
    case 8:
        return "SEP";
    case 9:
        return "OCT";
    case 10:
        return "NOV";
    case 11:
        return "DEC";
    default:
        std::cout << "invalid month";
        break;
    }
}

Date::Date()
{
    day = 1;
    month = Month(JANUARY);
    year = 1900;
}

Date::Date(Month month, int day, int year)
{
    this->month = month;
    this->day = day;
    this->year = year;
}

Date::Date(int day, Month month, int year) : Date(month, day, year)
{

    // this->day = day;
    // this->month = month;
    // this->year = year;
}

int Date::getDay()
{
    return day;
}

Month Date::getMonth()
{
    return month;
}

int Date::getYear()
{
    return year;
}

std::string Date::toString() const
{
    return integerToString(day) + "-" + monthToString(month) + "-" + integerToString(year);
}

bool Date::operator==(const Date &date2) const
{
    return day == date2.day && month == date2.month && year == date2.year;
}

bool Date::operator!=(const Date &date2) const
{
    return day != date2.day || month != date2.month || year != date2.year;
}

bool Date::operator<=(const Date &date2) const
{
    return year < date2.year ||
            ((year == date2.year) && month < date2.month) ||
            ((year == date2.year && month == date2.month) && day <= date2.day);
}

bool Date::operator<(const Date &date2) const
{
    return  year < date2.year ||
            ((year == date2.year) && month < date2.month) ||
            ((year == date2.year && month == date2.month) && day < date2.day);
}

Date Date::operator+(const int day)
{
    return Date(day+1, month, year);
}

int Date::operator-(const Date &date2)
{
    int sumMonthDays1 = 0;
    int sumMonthDays2 = 0;
    for (int i  = 0 ; i < month; i++) {
        sumMonthDays1 += daysInMonth(Month(i), year);
    }
    for (int i = 0; i < date2.month; i++) {
        sumMonthDays2 += daysInMonth(Month(i), year);
    }
    sumMonthDays1 += day;
    sumMonthDays2 += date2.day;
    int sumYearDays = 0;
    if (year == date2.year) {
        return abs(sumMonthDays1 - sumMonthDays2);
    } else {
        for (int i = date2.year; i < year; i++) {
            sumYearDays += isLeapYear(i) ? 365 : 366;
        }
        return sumYearDays + sumMonthDays1 - sumMonthDays2;
    }

}

std::ostream &operator<<(std::ostream & os, const Date &date)
{
    os << date.toString();
    return os;
}

Date operator++(Date &date, int)
{
    Date old = date;
    if (date.day < daysInMonth(date.month, date.year)) {
        date = Date(date.day+1, date.month, date.year);
    } else if (date.month < 11) {
        date = Date(1, Month(date.month+1), date.year);
    } else
        date = Date(1, Month(0), date.year+1);
    return old;
}
#ifndef LABELGENERATOR_H
#define LABELGENERATOR_H
#include 

class LabelGenerator {
public:
    LabelGenerator(std::string prefix, int number);

    std::string nextLabel();
private:
    std::string prefix;
    static int number;
};

#endif // LABELGENERATOR_H
#include "LabelGenerator.h"
#include "strlib.h"
#include 
#include 

using namespace std;

int LabelGenerator::number = 0;

LabelGenerator::LabelGenerator(string prefix, int number)
{
    this->prefix = prefix;
    this->number = number;
}

string LabelGenerator::nextLabel()
{
    string str = prefix + integerToString(number);
    number++;
    return str;
}
#ifndef RETIONAL_H
#define RETIONAL_H
#include 
#include 

class Rational {
public:
    Rational();
    Rational(int n);
    Rational(int x, int y);

    std::string toString();

    friend Rational operator+(Rational r1, Rational r2);
    friend Rational operator-(Rational r1, Rational r2);
    friend Rational operator*(Rational r1, Rational r2);
    friend Rational operator/(Rational r1, Rational r2);

    bool operator==(Rational &rat);
    bool operator<(Rational &rat);

private:
    int numerator;
    int denominator;
};

std::ostream & operator<<(std::ostream &os, Rational rat);

Rational operator+(Rational r1, Rational r2);
Rational operator-(Rational r1, Rational r2);
Rational operator*(Rational r1, Rational r2);
Rational operator/(Rational r1, Rational r2);

#endif // RETIONAL_H
#include "Retional.h"
#include "strlib.h"
int gcd(int x, int y)
{
    int r = x % y;
    while (r != 0) {
        x = y;
        y = r;
        r = x % y;
    }
}


Rational::Rational()
{
    numerator = 0;
    denominator = 1;
}

Rational::Rational(int n)
{
    numerator = n;
    denominator = 1;
}

Rational::Rational(int x, int y)
{
   if (y == 0) std::cerr << "Division by zero" << std::endl;
   if (x == 0) {
       numerator = 0;
       denominator = 1;
   } else {
       int g = gcd(abs(x), abs(y));
       numerator = x/g;
       denominator = abs(y)/g;
       if (y < 0) numerator = -numerator;
   }
}

std::string Rational::toString()
{
    if (denominator == 1) {
        return integerToString(numerator);
    } else {
        return integerToString(numerator) + "/" + integerToString(denominator);
    }
}

bool Rational::operator==(Rational &rat)
{
    return numerator == rat.numerator && denominator == rat.denominator;
}

bool Rational::operator<(Rational &rat)
{
    Rational temp = (*this) - rat;
    return numerator < 0;
}

Rational operator+(Rational r1, Rational r2)
{
    return Rational(r1.numerator*r2.denominator + r2.numerator*r1.denominator, r1.denominator *r2.denominator);
}

Rational operator-(Rational r1, Rational r2)
{
    return Rational(r1.numerator * r2.denominator - r2.numerator * r1.denominator, r1.denominator *r2.denominator);
}

Rational operator*(Rational r1, Rational r2)
{
    return Rational(r1.numerator * r2.numerator, r1.denominator*r2.denominator);
}

Rational operator/(Rational r1, Rational r2)
{
    return Rational(r1.numerator * r2.denominator, r1.denominator*r2.numerator);
}

std::ostream &operator<<(std::ostream &os, Rational rat)
{
    return os << rat.toString();
}
#ifndef STRLIB_H
#define STRLIB_H
#include 

std::string integerToString(int n);

#endif // STRLIB_H
#include 
#include 

std::string integerToString(int n)
{
    std::ostringstream stream;
    stream << n;
    return stream.str();
}
// #include "calendar.h"
#include "LabelGenerator.h"
#include 
#include 

using namespace std;
int main() {
    /* exercise 5
    Date defaultDate;
    cout << defaultDate.toString() << endl;
    Date date(JULY, 20, 1969);
    cout << date.toString() << endl;
    Date otherDay(20, JULY, 1969);
    cout << otherDay.toString() << endl;
    */

    /* exercise 6
    Date electionDay(6, NOVEMBER, 2012);
    Date inaugurationDay(21, JANUARY, 2013);
    cout << "electionDay < inaugurationDay " << ((electionDay < inaugurationDay) ? "true" : "false") << endl;

    cout << (inaugurationDay - electionDay) << endl;

    for (Date d = electionDay; d <= inaugurationDay; d++) {
        cout << d << endl;
    }
    */

    /* exercise 7
    LabelGenerator figureNumbers("Figure ", 1);
    LabelGenerator pointNumbers("P", 0);
    cout << "Figure numbers: ";
    for (int i = 0; i < 3; i++) {
        if (i > 0) cout << ", ";
        cout << figureNumbers.nextLabel();
    }
    cout << endl << "Point numbers: ";
    for (int i = 0; i < 5; i++) {
        if (i > 0) cout << ", ";
        cout << pointNumbers.nextLabel();
    }
    cout << endl << "More figures:  ";
    for (int i = 0; i < 3; i++) {
        if (i > 0) cout << ", ";
        cout << figureNumbers.nextLabel();
    }
    cout << endl;
    */


    return 0;
}

/*
 * output
 * exercise 5
 * 1-JAN-1900
 * 20-JUL-1969
 * 20-JUL-1969
 *
 * exercise 6
 * electionDay < inaugurationDay true
 * 76
 * 6-NOV-2012
 * 7-NOV-2012
 * 8-NOV-2012
 * 9-NOV-2012
 *
 * exercise 7
 * Figure numbers: Figure 0, Figure 1, Figure 2
 * Point numbers: P3, P4, P5, P6, P7
 * More figures:  Figure 8, Figure 9, Figure 10
 *
 */

Exercise 8主要写Rational相关接口,重载很多符号。

#include 
#include 
#include 
#include 
#include "rational.h"
#include 
#include 
#include 

using namespace std;

int stringToInteger(const std::string& str, int radix=10) {

    std::istringstream stream(str);
    stream >> std::setbase(radix);
    int value;
    stream >> value;
    return value;
}
void applyOperator(string op, stack &operandStack) {
    Rational result;
    Rational rhs = operandStack.top();
    operandStack.pop();
    Rational lhs = operandStack.top();
    operandStack.pop();
    char c = op[0];
    switch (c) {
    case '+': result = lhs + rhs; break;
    case '-': result = lhs - rhs; break;
    case '*': result = lhs * rhs; break;
    case '/': result = lhs / rhs; break;
    }
    cout << result << endl;
    operandStack.push(result);
}

void helpCommand() {
    cout << "Enter expressions in Reverse Polish Notation," << endl;
    cout << "in which operators follow the operands to which" << endl;
    cout << "they apply. Each line consists of a number, an" << endl;
    cout << "operator, or one of the following commands: " << endl;
    cout << " Q -- Quit the program" << endl;
    cout << " H -- Display this help message" << endl;
    cout << " C -- Clear the calculator stack" << endl;
}



int main() {
    cout << "RPN Calculator Simulation (type H for help)" << endl;

    stack operandStack;
    while (true) {
            cout << "> ";
    string line;
    cin >> line;
    if (line == "Q") return 0;
    else if (line == "H")
        helpCommand();
    else if (line == "C") {
        while (!operandStack.empty()) {
            operandStack.pop();
        }
    }
    else if (isdigit(line[0])) {
        operandStack.push(stringToInteger(line));
    }  else if (line == "/") {
        Rational result;
        Rational rhs = operandStack.top();
        int i = stringToInteger(rhs.toString());
        operandStack.pop();
        Rational lhs = operandStack.top();
        int j = stringToInteger(lhs.toString());
        operandStack.pop();
        result = Rational(j, i);
        cout << result.toString() << endl;
        operandStack.push(result);
    } else {
        applyOperator(line, operandStack);
    }
}

    return 0;
}

/*
 * output
 * exercise 9
 * RPN Calculator Simulation (type H for help)
 * > 1
 * > 2
 * > /
 * 1/2
 * > 1
 * > 3
 * > /
 * 1/3
 * > 1
 * > 6
 * > /
 * 1/6
 * > +
 * 1/2
 * > +   
 * 1
 * > Q
 */
#include 
#include "tokenscanner.h"
#include 
#include 
#include "filelib.h"
#include "console.h"
#include "stack.h"
#include "strlib.h"
using namespace std;

int main() {
    /* exercise 10
    ifstream infile;
    promptUserForFile(infile, "Input file: ");

    TokenScanner ts(infile);
    ts.ignoreWhitespace();

    ifstream wordsFile;
    wordsFile.open("EnglishWords.dat");
    string str;
    Vector vc;
    while (getline(wordsFile, str)) {
        vc.push_back(str);
    }

    // exercise 11
    while (ts.hasMoreTokens()) {
        bool included = false;
        string next = ts.nextToken();
        for (int i = 0; i < vc.size(); i++) {
            if (next == vc[i]) {
                cout <<"\"" << vc[i] << "\"" << " is in the dictionary" << endl;
                included = true;
                break;
            }
        }
        if (!included)
            cout <<"\"" << next << "\"" << " is not in the dictionary" << endl;
    }
    */


    string str;
    cout << "> ";
    while (getline(cin, str)) {
            TokenScanner ts(str);
            ts.ignoreWhitespace();
            ts.addWordCharacters(".");
            Stack stack;
            while (ts.hasMoreTokens()) {
                string temp = ts.nextToken();
                if (temp != "/" && temp != "*") {
                    stack.push(temp);
                } else {
                    if (temp == "/") {
                        double s1 = stringToReal(stack.pop());
                        double s2 = stringToReal(ts.nextToken());
                        stack.push(realToString(s1/s2));
                    }
                    if (temp == "*") {
                        double s1 = stringToReal(stack.pop());
                        double s2 = stringToReal(ts.nextToken());
                        stack.push(realToString(s1*s2));
                    }
                }
            }
            double s1, s2;
            Stack stack1;
            while (!stack.isEmpty()) {
                stack1.push(stack.pop());
            }
            while (!stack1.isEmpty()) {
                s1 = stringToReal(stack1.pop());

                if (stack1.isEmpty()) {
                    cout << realToString(s1) << endl;
                    cout << "> ";
                    break;
                }
                string s = stack1.pop();

                s2 = stringToReal(stack1.pop());

                if (s == "+") stack1.push(realToString(s1+s2));
                if (s == "-") stack1.push(realToString(s1-s2));
            }
            stack.clear();
    }
    return 0;
}

/*
 * output
 * exercise 10
 * Input file: SampleParagraph.txt
 * "TokenScanner" is not in the dictionary
 * "EnglishWords" is not in the dictionary
 * "dat" is in the dictionary
 * "SpellCheck" is not in the dictionary
 *
 * exercise 11
 * > 2 + 2
 * 4
 * > 355 / 113
 * 3.14159
 * > 20.4 - 3.6 * 2.5
 * 11.4
 * > 4+9-2*16+1/3*6
 * -17
 * > 4+9-2*16+1/3*6-67+8*2-3+26-1/34+3/7+2-5
 * -47.6008
 */

exercise 13, exercise 14, exercise 15是实现TokenScanner的实现,

这个还很难,所以贴上lib库上面的代码,最重要要会用。

/*
 * File: tokenscanner.cpp
 * ----------------------
 * Implementation for the TokenScanner class.
 * 
 * @version 2016/11/26
 * - added getInput method
 * - replaced occurrences of string with const string& for efficiency
 * - alphabetized method ordering
 * - added operator << for printing a scanner
 * @version 2014/10/08
 * - removed 'using namespace' statement
 */

#include "tokenscanner.h"
#include 
#include 
#include "error.h"
#include "strlib.h"
#include "stack.h"

TokenScanner::TokenScanner() {
    initScanner();
    setInput("");
}

TokenScanner::TokenScanner(std::istream& infile) {
    initScanner();
    setInput(infile);
}

TokenScanner::TokenScanner(const std::string& str) {
    initScanner();
    setInput(str);
}

TokenScanner::~TokenScanner() {
    if (stringInputFlag) {
        delete isp;
    }
}

void TokenScanner::addOperator(const std::string& op) {
    StringCell* cp = new StringCell;
    cp->str = op;
    cp->link = operators;
    operators = cp;
}

void TokenScanner::addWordCharacters(const std::string& str) {
    wordChars += str;
}

int TokenScanner::getChar() {
    return isp->get();
}

std::string TokenScanner::getInput() const {
    return buffer;
}

int TokenScanner::getPosition() const {
    if (!savedTokens) {
        return int(isp->tellg());
    } else {
        return int(isp->tellg()) - savedTokens->str.length();
    }
}

std::string TokenScanner::getStringValue(const std::string& token) const {
    std::string str = "";
    int start = 0;
    int finish = token.length();
    if (finish > 1 && (token[0] == '"' || token[0] == '\'')) {
        start = 1;
        finish--;
    }
    for (int i = start; i < finish; i++) {
        char ch = token[i];
        if (ch == '\\') {
            ch = token[++i];
            if (isdigit(ch) || ch == 'x') {
                int base = 8;
                if (ch == 'x') {
                    base = 16;
                    i++;
                }
                int result = 0;
                int digit = 0;
                while (i < finish) {
                    ch = token[i];
                    if (isdigit(ch)) {
                        digit = ch - '0';
                    } else if (isalpha(ch)) {
                        digit = toupper(ch) - 'A' + 10;
                    } else {
                        digit = base;
                    }
                    if (digit >= base) {
                        break;
                    }
                    result = base * result + digit;
                    i++;
                }
                ch = char(result);
                i--;
            } else {
                switch (ch) {
                case 'a': ch = '\a'; break;
                case 'b': ch = '\b'; break;
                case 'f': ch = '\f'; break;
                case 'n': ch = '\n'; break;
                case 'r': ch = '\r'; break;
                case 't': ch = '\t'; break;
                case 'v': ch = '\v'; break;
                case '"': ch = '"'; break;
                case '\'': ch = '\''; break;
                case '\\': ch = '\\'; break;
                }
            }
        }
        str += ch;
    }
    return str;
}

TokenType TokenScanner::getTokenType(const std::string& token) const {
    if (token.empty()) {
        return TokenType(EOF);
    }

    char ch = token[0];
    if (isspace(ch)) {
        return SEPARATOR;
    } else if (ch == '"' || (ch == '\'' && token.length() > 1)) {
        return STRING;
    } else if (isdigit(ch)) {
        return NUMBER;
    } else if (isWordCharacter(ch)) {
        return WORD;
    } else {
        return OPERATOR;
    }
}

bool TokenScanner::hasMoreTokens() {
    std::string token = nextToken();
    saveToken(token);
    return !token.empty();
}

void TokenScanner::ignoreComments() {
    ignoreCommentsFlag = true;
}

void TokenScanner::ignoreWhitespace() {
    ignoreWhitespaceFlag = true;
}

bool TokenScanner::isWordCharacter(char ch) const {
    return isalnum(ch) || wordChars.find(ch) != std::string::npos;
}

std::string TokenScanner::nextToken() {
    if (savedTokens) {
        StringCell* cp = savedTokens;
        std::string token = cp->str;
        savedTokens = cp->link;
        delete cp;
        return token;
    }

    while (true) {
        if (ignoreWhitespaceFlag) {
            skipSpaces();
        }
        int ch = isp->get();
        if (ch == '/' && ignoreCommentsFlag) {
            ch = isp->get();
            if (ch == '/') {
                while (true) {
                    ch = isp->get();
                    if (ch == '\n' || ch == '\r' || ch == EOF) {
                        break;
                    }
                }
                continue;
            } else if (ch == '*') {
                int prev = EOF;
                while (true) {
                    ch = isp->get();
                    if (ch == EOF || (prev == '*' && ch == '/')) {
                        break;
                    }
                    prev = ch;
                }
                continue;
            }
            if (ch != EOF) {
                isp->unget();
            }
            ch = '/';
        }
        if (ch == EOF) {
            return "";
        }
        if ((ch == '"' || ch == '\'') && scanStringsFlag) {
            isp->unget();
            return scanString();
        }
        if (isdigit(ch) && scanNumbersFlag) {
            isp->unget();
            return scanNumber();
        }
        if (isWordCharacter(ch)) {
            isp->unget();
            return scanWord();
        }
        std::string op = std::string(1, ch);
        while (isOperatorPrefix(op)) {
            ch = isp->get();
            if (ch == EOF) {
                break;
            }
            op += ch;
        }
        while (op.length() > 1 && !isOperator(op)) {
            isp->unget();
            op.erase(op.length() - 1, 1);
        }
        return op;
    }
}

void TokenScanner::saveToken(const std::string& token) {
    StringCell* cp = new StringCell;
    cp->str = token;
    cp->link = savedTokens;
    savedTokens = cp;
}

void TokenScanner::scanNumbers() {
    scanNumbersFlag = true;
}

void TokenScanner::scanStrings() {
    scanStringsFlag = true;
}

void TokenScanner::setInput(std::istream& infile) {
    stringInputFlag = false;
    isp = &infile;
    savedTokens = nullptr;
}

void TokenScanner::setInput(const std::string& str) {
    stringInputFlag = true;
    buffer = str;
    isp = new std::istringstream(buffer);
    savedTokens = nullptr;
}

void TokenScanner::ungetChar(int) {
    isp->unget();
}

void TokenScanner::verifyToken(const std::string& expected) {
    std::string token = nextToken();
    if (token != expected) {
        std::string msg = "TokenScanner::verifyToken: Found \"" + token + "\""
                + " when expecting \"" + expected + "\"";
        if (!buffer.empty()) {
            msg += "\ninput = \"" + buffer + "\"";
        }
        error(msg);
    }
}

/* Private methods */

void TokenScanner::initScanner() {
    ignoreWhitespaceFlag = false;
    ignoreCommentsFlag = false;
    scanNumbersFlag = false;
    scanStringsFlag = false;
    operators = nullptr;
}

/*
 * Implementation notes: isOperator, isOperatorPrefix
 * --------------------------------------------------
 * These methods search the list of operators and return true if the
 * specified operator is either in the list or a prefix of an operator
 * in the list, respectively.  This code could be made considerably more
 * efficient by implementing operators as a trie.
 */
bool TokenScanner::isOperator(const std::string& op) {
    for (StringCell *cp = operators; cp != nullptr; cp = cp->link) {
        if (op == cp->str) {
            return true;
        }
    }
    return false;
}

bool TokenScanner::isOperatorPrefix(const std::string& op) {
    for (StringCell* cp = operators; cp != nullptr; cp = cp->link) {
        if (startsWith(cp->str, op)) {
            return true;
        }
    }
    return false;
}

/*
 * Implementation notes: scanNumber
 * --------------------------------
 * Reads characters until the scanner reaches the end of a legal number.
 * The function operates by simulating what computer scientists
 * call a finite-state machine.  The program uses the variable
 * state to record the history of the process and
 * determine what characters would be legal at this point in time.
 */
std::string TokenScanner::scanNumber() {
    std::string token = "";
    NumberScannerState state = INITIAL_STATE;
    while (state != FINAL_STATE) {
        int ch = isp->get();
        switch (state) {
        case INITIAL_STATE:
            if (!isdigit(ch)) {
                error("TokenScanner::scanNumber: internal error: illegal call");
            }
            state = BEFORE_DECIMAL_POINT;
            break;
        case BEFORE_DECIMAL_POINT:
            if (ch == '.') {
                state = AFTER_DECIMAL_POINT;
            } else if (ch == 'E' || ch == 'e') {
                state = STARTING_EXPONENT;
            } else if (!isdigit(ch)) {
                if (ch != EOF) {
                    isp->unget();
                }
                state = FINAL_STATE;
            }
            break;
        case AFTER_DECIMAL_POINT:
            if (ch == 'E' || ch == 'e') {
                state = STARTING_EXPONENT;
            } else if (!isdigit(ch)) {
                if (ch != EOF) {
                    isp->unget();
                }
                state = FINAL_STATE;
            }
            break;
        case STARTING_EXPONENT:
            if (ch == '+' || ch == '-') {
                state = FOUND_EXPONENT_SIGN;
            } else if (isdigit(ch)) {
                state = SCANNING_EXPONENT;
            } else {
                if (ch != EOF) {
                    isp->unget();
                }
                isp->unget();
                state = FINAL_STATE;
            }
            break;
        case FOUND_EXPONENT_SIGN:
            if (isdigit(ch)) {
                state = SCANNING_EXPONENT;
            } else {
                if (ch != EOF) {
                    isp->unget();
                }
                isp->unget();
                isp->unget();
                state = FINAL_STATE;
            }
            break;
        case SCANNING_EXPONENT:
            if (!isdigit(ch)) {
                if (ch != EOF) {
                    isp->unget();
                }
                state = FINAL_STATE;
            }
            break;
        default:
            state = FINAL_STATE;
            break;
        }
        if (state != FINAL_STATE) {
            token += char(ch);
        }
    }
    return token;
}

/*
 * Implementation notes: scanString
 * --------------------------------
 * Reads and returns a quoted string from the scanner, continuing until
 * it scans the matching delimiter.  The scanner generates an error if
 * there is no closing quotation mark before the end of the input.
 */
std::string TokenScanner::scanString() {
    std::string token = "";
    char delim = isp->get();
    token += delim;
    bool escape = false;
    while (true) {
        int ch = isp->get();
        if (ch == EOF) {
            error("TokenScanner::scanString: found unterminated string");
        }
        if (ch == delim && !escape) {
            break;
        }
        escape = (ch == '\\') && !escape;
        token += ch;
    }
    return token + delim;
}

/*
 * Implementation notes: scanWord
 * ------------------------------
 * Reads characters until the scanner reaches the end of a sequence
 * of word characters.
 */
std::string TokenScanner::scanWord() {
    std::string token = "";
    while (true) {
        int ch = isp->get();
        if (ch == EOF) {
            break;
        }
        if (!isWordCharacter(ch)) {
            isp->unget();
            break;
        }
        token += char(ch);
    }
    return token;
}

/*
 * Implementation notes: skipSpaces
 * --------------------------------
 * Advances the position of the scanner until the current character is
 * not a whitespace character.
 */
void TokenScanner::skipSpaces() {
    while (true) {
        int ch = isp->get();
        if (ch == EOF) {
            return;
        }
        if (!isspace(ch)) {
            isp->unget();
            return;
        }
    }
}

std::ostream& operator <<(std::ostream& out, const TokenScanner& scanner) {
    out << "TokenScanner{";
    bool first = true;
    if (!scanner.buffer.empty()) {
        out << "input=\"" << scanner.buffer << "\"";
        first = false;
    }
    out << (first ? "" : ",") << "position=" << scanner.getPosition();
    first = false;

    if (scanner.scanNumbersFlag) {
        out << (first ? "" : ",") << "scanNumbers";
        first = false;
    }
    if (scanner.scanStringsFlag) {
        out << (first ? "" : ",") << "scanStrings";
        first = false;
    }
    if (!scanner.wordChars.empty()) {
        out << (first ? "" : ",") << "wordChars=[" << scanner.wordChars << "]";
        first = false;
    }
    if (scanner.ignoreWhitespaceFlag) {
        out << (first ? "" : ",") << "ignoreWhitespace";
        first = false;
    }
    if (scanner.ignoreCommentsFlag) {
        out << (first ? "" : ",") << "ignoreComments";
        first = false;
    }
    out << "}";
    return out;
}

Chapter 7 Introduction to Recursion

7.1 A simple example of recursion

7.2 The factorial function

7.3 The Fibonacci function

7.4 Checking palindromes

7.5 The binary search algorithm

7.6 Mutual recursion

7.7 Thinking recursively

总结主要讲述的是迭代的介绍。

#include 
#include 

using namespace std;

const int MIN_INDEX = 17;
const int MAX_INDEX = 20;

int fib(int n);

int main() {
    cout << "This program lists the Fibonacci sequence." << endl;
    for (int i = MIN_INDEX; i <= MAX_INDEX; i++) {
        if (i < 10) cout << " ";
        cout << "fib(" << i << ")";
        cout << " = " << setw(4) << fib(i) << endl;
    }
    return 0;
}
int fib(int n) {
    if (n < 2) {
        return n;
    } else {
        return fib(n-1) + fib(n-2);
    }
}

/*
 * output
 * This program lists the Fibonacci sequence.
 * fib(17) = 1597
 * fib(18) = 2584
 * fib(19) = 4181
 * fib(20) = 6765
 */
1. recursive 迭代 iterative 循环 yes
2. 迭代重新调动自己
3. n/10可能不是100的整数倍
4. for while
5. 不断减小,而且有最小解
6. 符合5的规则
7. 尽快解决问题
8. 不断调用函数然后返回
9. 自身解
10. 编程的时候解决
11. 1
12. 包裹函数
13. 出问题溢出
14. 不会
15. 不断减小量
16. 不知道
17. 死循环
18. n = 3的时候出问题
#include 
#include 
using namespace std;

static int count1 = 0;
static int count2 = 0;

int cannonball(int height) {
    if (height == 1)
        return 1;
    else
        return cannonball(height-1) + height * height;

}

// exercise 2
int raiseToPower(int n, int k) {
    if (k == 0)
        return 1;
    else
        return raiseToPower(n, k-1) * n;
}

int distance(int i) {
    if (i == 1) {
        return 1;
    } else if (i == 2) {
        return 3;
    } else {
        return 2 * distance(i-1);
    }
}

double getTitiusBodeDistance(int k) {
    return (4+distance(k))/10.0;
}

int gcd(int x, int y) {
    if (x % y == 0)
        return y;
    else
        gcd(y, x%y);
}
/*
int fib(int i) {
    if (i == 0) return 0;
    if (i == 1) return 1;
    vector vec;
    vec.push_back(0);
    vec.push_back(1);
    for (int k = 2; k <= i; k++) {
        vec.push_back(vec[k-1]+vec[k-2]);
    }
    return vec[i];
}
*/
int countFib1(int n) {
    count1++;
    if (n < 2)
        return n;
    else
        return countFib1(n-1) + countFib1(n-2);
}

int additiveSequence(int n, int t0, int t1) {
    count2++;
    if (n == 0) return t0;
    if (n == 1) return t1;
    return additiveSequence(n-1, t1, t0+t1);
}

int countFib2(int n) {
    count2++;
    return additiveSequence(n, 0, 1);
}

int main() {
    /* exercise 1
    cout << cannonball(2) << endl;
    cout << cannonball(4) << endl;
    */

    /* exercise 3
    for (int i = 1; i <= 7; i++) {
        cout << getTitiusBodeDistance(i) << endl;
    }
    */

    /* exercise 4
    cout << gcd(4, 2) << endl;
    cout << gcd(8, 12) << endl;
    */

    /*
    cout << fib(5) << endl;
    cout << fib(8) << endl;
    */

    cout << "This progrm counts the numer of calls made by the two algorithms used to"
         << "compute the Fibonacci sequence" << endl;
    cout << "   n       fib1        fib2" << endl;
    cout << "  --       ------          -----" << endl;
    for (int i = 0; i <= 12 ; i++) {
        count1 = 0;
        count2 = 0;
        countFib1(i);
        countFib2(i);
        cout << "   " << i << "          " << count1 << "        " << count2 << endl;
    }

    return 0;
}

/*
 * output
 * exercise 1
 * 5
 * 30
 *
 * exercise 3
 * 0.5
 * 0.7
 * 1
 * 1.6
 * 2.8
 * 5.2
 * 10
 *
 * exercise 4
 * 2
 * 4
 *
 * exercise 5
 * 5
 * 21
 *
 * exercise 6
 * This progrm counts the numer of calls made by the two algorithms used tocompute the Fibonacci sequence
 *  n       fib1        fib2
 *  --       ------          -----
 *   0          1        2
 *  1          1        2
 *   2          3        3
 *   3          5        4
 *   4          9        5
 *   5          15        6
 *   6          25        7
 *  7          41        8
 *  8          67        9
 *   9          109        10
 *   10          177        11
 *   11          287        12
 *  12          465        13
 *
 *
 */
#include 
#include 

using namespace std;

int digitSum(int number) {
    if (number < 10)
        return number;
    else {
        return digitSum(number/10) + number%10;
    }
}

int digitRoot(int number) {
    while (digitSum(number) >= 10) {
       number = digitSum(number);
    }
    return digitSum(number);
}

int c(int n, int k) {
    if (k == 0) return 1;
    if (k == n) return 1;
    return c(n-1, k-1) + c(n-1, k);
}

string reverse(string str) {
    if (str.length() <= 1) return str;
    return str[str.length()-1] + reverse(str.substr(1, str.length()-2)) + str[0];
}

string recursiveIntegerToString(int number) {
    if (number < 10) {
        string str = "";
        str += char(number+'0');
        return str;
    }
    else {
        return recursiveIntegerToString(number/10) + char (number%10 + '0');
    }
}

int main() {
    /* exercise 7
    cout << digitSum(1729) << endl;
    */

    /* exercise 8
    cout << digitRoot(1729) << endl;
    */

    /* exercise 9
    cout << c(6, 2) << endl;
    */

    /* exercise 10
    cout << reverse("program") << endl;
    */
    cout << recursiveIntegerToString(1) << endl;
    cout << recursiveIntegerToString(1729) << endl;

}

/*
 * output
 * exercise 7
 * 19
 *
 * exercise 8
 * 1
 *
 * exercise 9
 * 15
 *
 * exercise 10
 * margorp
 *
 * exercise 11
 * 1
 * 1729
 */




























你可能感兴趣的:(C++)