C++程序设计原理与实践 习题答案 第六章 第6章习题答案

第六章 习题答案


6.2 和 6.3


//
// Calculator, add "{ }" and '!' operators
// 
//

#include"../../std_lib_facilities.h"

//------------------------------------------------------------------------------

class Token {
public:
    char kind;        // what kind of token
    double value;     // for numbers: a value 
    Token(char ch)    // make a Token from a char
        :kind(ch), value(0) { }
    Token(char ch, double val)     // make a Token from a char and a double
        :kind(ch), value(val) { }
};

class Token_stream {
public:
    Token_stream();
    Token get();        // get a token
    void putback(Token t);  // put back a token
private:
    bool full{ false }; // is buffer full?
    Token buffer;   // a buffer for token by putback()
};

//------------------------------------------------------------------------------

// The constructor just sets full to indicate that the buffer is empty:
Token_stream::Token_stream()
    :full(false), buffer(0)    // no Token in buffer
{
}


Token Token_stream::get()    // read a token from cin
{
    if (full)
    {
        full = false;
        return buffer;
    }
    char ch;
    cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)

    switch (ch) {
    case '=':    // for "print"
    case 'x':    // for "quit"
    case '(': case ')': case '{': case '}':
    case '+': case '-': case '*': case '/': case '!':
        return Token{ ch };        // let each character represent itself
    case '.':
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    {
        cin.putback(ch);         // put digit back into the input stream
        double val;
        cin >> val;              // read a floating-point number
        return Token('8', val);   // let '8' represent "a number"
    }
    default:
        error("Bad token");
    }
}

// The putback() member function puts its argument back into the Token_stream's buffer:
void Token_stream::putback(Token t)
{
    if (full) error("putback() into a full buffer.");
    buffer = t;
    full = true;
}

//------------------------------------------------------------------------------

Token_stream ts;    // provides get() and putback()

//------------------------------------------------------------------------------

double expression();  // read and evaluate a Expression

//------------------------------------------------------------------------------

double primary()     // read and evaluate a Primary
{
    Token t = ts.get();
    switch (t.kind) {
    case '(':    // handle '(' expression ')'
    {
        double d = expression();
        t = ts.get();
        if (t.kind != ')') error("')' expected");
        return d;
    }
    case '{':   // handle '{' expression '}'
    {
        double d = expression();
        t = ts.get();
        if (t.kind != '}') error("'}' expected");
        return d;
    }
    case '8':            // we use '8' to represent a number
    {
        Token tt = ts.get();
        if (tt.kind == '!')
        {
            int x = narrow_cast<int>(t.value);  //defined in std_lib_facilities
            if (x == 0)
                return 1;
            for (int i = x - 1; i > 0; i--)
                x *= i;
            return x;
        }
        else
            ts.putback(tt);
        return t.value;  // return the number's value
    }
    case 'x':
    case '=':
        ts.putback(t);
        return t.value;
    default:
        error("primary expected");
    }
}

//------------------------------------------------------------------------------

double term()
{
    double left = primary();
    Token t = ts.get();     // get the next token

    while (true) {
        switch (t.kind) {
        case '*':
            left *= primary();
            t = ts.get();
            break;
        case '/':
        {
            double d = primary();
            if (d == 0) error("divide by zero");
            left /= d;
            t = ts.get();
            break;
        }
        default:
            ts.putback(t);
            return left;
        }
    }
}

//------------------------------------------------------------------------------

double expression()
{
    double left = term();      // read and evaluate a Term
    Token t = ts.get();     // get the next token
    while (true) {
        switch (t.kind) {
        case '+':
            left += term();    // evaluate Term and add
            t = ts.get();
            break;
        case '-':
            left -= term();    // evaluate Term and subtract
            t = ts.get();
            break;
        default:
            ts.putback(t);
            return left;       // finally: no more + or -: return the answer
        }
    }
}


//------------------------------------------------------------------------------

int main()
try {
    cout << "Welcome to our simple calculator.\n";
    cout << "Please enter expressions using floating-point numbers.\n";
    cout << "You can use \" + - * / ! \" operators, '=' to output result, and 'x' to quit.\n";

    Token t{ 0 };
    double val{ 0 };

    while (cin)
    {
        t = ts.get();
        if (t.kind == 'x')
            break;
        else if (t.kind == '=')
            cout << "= " << val << '\n';
        else
            ts.putback(t);
        val = expression();
    }

    keep_window_open("~0");
    return 0;
}
catch (exception& e) {
    cerr << e.what() << endl;
    keep_window_open("~1");
    return 1;
}
catch (...) {
    cerr << "exception \n";
    keep_window_open("~2");
    return 2;
}

6.6

#include"../../std_lib_facilities.h"

vector<string>conj{ "and","or","but" };
vector<string>article{ "a", "an", "the" };
vector<string>noun{ "birds","fish","C++" };
vector<string>verb{ "rules","fly","swim" };


bool search_word(string word, vector<string>words)
{
    for (string x : words)
        if (word == x)
            return true;
    return false;
}

bool sentence()
{
    string word;
    string sents;
    bool flag = false;  // 标识是否在单词集合中
    
    cin >> word;
    if (!cin)
        error("can't read a word.");
    //首先判断是否是冠词
    flag = search_word(word, article);
    if (flag)
    {
        cin >> word;
        if (!cin)
            error("can't read a word.");
    }
    //然后判断是否为名词
    flag = search_word(word, noun);
    if (flag)
    {
        cin >> word;
        if (!cin)
            error("can't read a word.");
    }
    else
        return false;   //如果不是名词,那么根据我们的简单语法,这不是一个句子
    //之后判断是否为动词
    flag = search_word(word, verb);
    char dot;   //用于读入可能的dot
    if (flag)
    {
        cin >> dot; //读入可能的句号
        if (!cin)
            error("can't read a word.");
    }
    else
        return false;   //如果不是动词,那么根据我们的简单语法,这不是一个句子
    //最后判断是否为结束的句号或者连词
    if (dot == '.')
        return true;
    else
    {
        cin.putback(dot);
        cin >> word;
        if (!cin)
            error("can't read a word.");
    }
    flag = search_word(word, conj);
    if (flag)
        return sentence();      //连词后要接一个新的句子,那么问题转化为判断新的句子是否符合语法了。
    else
        return false;
}

//------------------------------------------------------------------------------

int main()
try {
    cout << "Enter a English sentence, the program will output \"OK\" or \"not OK\".\n";
    cout << "Your input sentences must have none, verbs and a '.' with two space between '.',";
    cout << "article and conjunction is optional.\n";
    cout << "enter ~ to quit\n";

    char ch;
    bool is_right{ false };

    while (cin)
    {
        cin >> ch;
        if (ch == '~')
            break;
        else
            cin.putback(ch);
        is_right = sentence();
        cout << (is_right ? "OK" : "not OK") << '\n';
    }

    keep_window_open("~0");
    return 0;
}
catch (exception& e) {
    cerr << e.what() << endl;
    keep_window_open("~1");
    return 1;
}
catch (...) {
    cerr << "exception \n";
    keep_window_open("~2");
    return 2;
}

6.7

//
// Calculator, deal with logic expression
// ! ~ & | ^
//

#include"../../std_lib_facilities.h"

//------------------------------------------------------------------------------

class Token {
public:
    char kind;        // what kind of token
    int value;     // for numbers: a value 
    Token(char ch)    // make a Token from a char
        :kind(ch), value(0) { }
    Token(char ch, int val)     // make a Token from a char and a int
        :kind(ch), value(val) { }
};

class Token_stream {
public:
    Token_stream();
    Token get();        // get a token
    void putback(Token t);  // put back a token
private:
    bool full{ false }; // is buffer full?
    Token buffer;   // a buffer for token by putback()
};

//------------------------------------------------------------------------------

// The constructor just sets full to indicate that the buffer is empty:
Token_stream::Token_stream()
    :full(false), buffer(0)    // no Token in buffer
{
}


Token Token_stream::get()    // read a token from cin
{
    if (full)
    {
        full = false;
        return buffer;
    }
    char ch;
    cin >> ch;    // note that >> skips whitespace (space, newline, tab, etc.)

    switch (ch) {
    case '=':    // for "print"
    case 'q':    // for "quit"
    case '(': case ')': case '{': case '}':
    case '~': case '!': case '^': case '&': case '|':
        return Token{ ch };        // let each character represent itself
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
    {
        cin.putback(ch);         // put digit back into the input stream
        int val;
        cin >> val;              // read a floating-point number
        return Token('8', val);   // let '8' represent "a number"
    }
    default:
        error("Bad token");
    }
}

// The putback() member function puts its argument back into the Token_stream's buffer:
void Token_stream::putback(Token t)
{
    if (full) error("putback() into a full buffer.");
    buffer = t;
    full = true;
}

//------------------------------------------------------------------------------

Token_stream ts;    // provides get() and putback()

//------------------------------------------------------------------------------

int expression();  // read and evaluate a Expression

//------------------------------------------------------------------------------

int primary()     // read and evaluate a Primary
{
    Token t = ts.get();
    switch (t.kind) {
    case '(':    // handle '(' expression ')'
    {
        int d = expression();
        t = ts.get();
        if (t.kind != ')') error("')' expected");
        return d;
    }
    case '{':   // handle '{' expression '}'
    {
        int d = expression();
        t = ts.get();
        if (t.kind != '}') error("'}' expected");
        return d;
    }
    case '8':            // we use '8' to represent a number
    {
        Token tt = ts.get();
        if (tt.kind == '!')     //处理阶乘,这里的!符号是后置的
        {
            int x = narrow_cast<int>(t.value);  //defined in std_lib_facilities
            if (x == 0)
                return 1;
            for (int i = x - 1; i > 0; i--)
                x *= i;
            return x;
        }
        else
            ts.putback(tt);
        return t.value;  // return the number's value
    }
    case '!':
    {
        int right = primary();
        return !right;
    }
    case '~':
    {
        int right = primary();
        return ~right;
    }
    case 'q':
    case '=':
        ts.putback(t);
        return t.value;
    default:
        error("primary expected");
    }
}

//------------------------------------------------------------------------------

int term_and()
{
    int left = primary();
    Token t = ts.get();     // get the next token

    while (true) {
        switch (t.kind) {
        case '&':
            left &= primary();
            t = ts.get();
            break;
        default:
            ts.putback(t);
            return left;
        }
    }
}

//------------------------------------------------------------------------------

int term_xor()
{
    int left = term_and();
    Token t = ts.get();     // get the next token

    while (true) {
        switch (t.kind) {
        case '^':
            left ^= term_and();
            t = ts.get();
            break;
        default:
            ts.putback(t);
            return left;
        }
    }
}

//------------------------------------------------------------------------------

int expression()
{
    int left = term_xor();      // read and evaluate a Term
    Token t = ts.get();     // get the next token
    while (true) {
        switch (t.kind) {
        case '|':
            left |= term_xor();    // evaluate Term and add
            t = ts.get();
            break;
        default:
            ts.putback(t);
            return left;       // finally: no more + or -: return the answer
        }
    }
}


//------------------------------------------------------------------------------

int main()
try {
    cout << "Welcome to our simple logic calculator.\n";
    cout << "Please enter logic expressions using integer numbers.\n";
    cout << "You can use \" ! ~ & ^ | \" operators, '=' to output result, and 'q' to quit.\n";

    Token t{ 0 };
    int val{ 0 };

    while (cin)
    {
        t = ts.get();
        if (t.kind == 'q')
            break;
        else if (t.kind == '=')
            cout << "= " << val << '\n';
        else
            ts.putback(t);
        val = expression();
    }

    keep_window_open("~0");
    return 0;
}
catch (exception& e) {
    cerr << e.what() << endl;
    keep_window_open("~1");
    return 1;
}
catch (...) {
    cerr << "exception \n";
    keep_window_open("~2");
    return 2;
}

6.10

#include"../../std_lib_facilities.h"

int factorial(int n)
{
	if (n < 0)
		error("N factorial, N can't lower than zero");
	int fac = 1;
	while (n > 1)
		fac *= n--;
	return fac;
}

int permutations(int a, int b)
{
	// P(a, b)
	if (a < b || a < 1 || b < 1)
		error("bad permutation sizes");
	return factorial(a) / factorial(a - b);
}

int combinations(int a, int b)
{
	return permutations(a, b) / factorial(b);
}

int main()
try {
	cout << "This calculator gives two functions of calculating permutation and combination\n\n";
	cout << "You should choose the function you want, like C or P" << endl;
	cout << "enter a size of set(a) and a size of subset(b), a must bigger than b" << endl;
	cout << "For example: C 7 3" << endl;
	cout << "The calculator will calculate combination of C(7,3) and output 35 as result\n";
	cout << "Enter 'q' or \"quit\" to quit\n";

	string choice;
	while (true)
	{
		cin >> choice;
		if (choice[0] == 'P' || choice[0] == 'p' || !_stricmp(choice.c_str(), "permutation"))
		{
			int a{ 0 }, b{ 0 };
			cin >> a >> b;
			int p = permutations(a, b);
			cout << "P(" << a << ',' << b << ") = " << p << endl;
		}
		else if (choice[0] == 'C' || choice[0] == 'c' || !_stricmp(choice.c_str(), "combination"))
		{
			int a{ 0 }, b{ 0 };
			cin >> a >> b;
			int c = combinations(a, b);
			cout << "C(" << a << ',' << b << ") = " << c << endl;
		}
		else if (choice[0] == 'q' || !_stricmp(choice.c_str(), "quit"))
			break;
		else
			cout << "Please enter right function choice." << endl;
		cout << "Try again!" << endl;
	}
	cout << "Bye!\n";

	return 0;
}
catch (runtime_error& e) {
	cerr << e.what() << endl;
	return 1;
}
catch (...) {
	cerr << "exception \n";
	return 2;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为编写实际的应用程序做好准备:无论你是为了进行软件开发还是进行其他领域的工作。《C++程序设计原理实践(英文版)》假定你的最终目标是学会编写实际有用的程序。以基本概念和基本技术为重点:与传统的C++教材相比,《C++程序设计原理实践(英文版)》对基本概念和基本技术的介绍更为深入。这会为你编写有用、正确.易维护和有效的代码打下坚实的基础。, 用现代C++语言编程:, 《C++程序设计原理实践(英文版)》一方面介绍了通用的程序设计方法(包括面向对象程序设计和泛型程序设计)。另一方面还对软件开发实践中使用最广泛的程序设计语言——C++进行了很好的介绍。《C++程序设计原理实践(英文版)》从开篇就开始介绍现代C++程序设计技术,并介绍了大量关于如何使用C++标准库来简化程序设计的内容。, 适用于初学者以及任何希望学习新知识的人:, 《C++程序设计原理实践(英文版)》主要是为那些从未编写过程序的人编写的。而且已经由超过1000名大学一年级新生试用过。不过,对于专业人员和高年级学生来说,通过观察公认的程序设计大师如何处理编程中的各种问题。同样也会获得新的领悟和指引。, 提供广阔的视野:, 《C++程序设计原理实践(英文版)》第一部分非常广泛地介绍了基本程序设计技术,包括基本概念、设计和编程技术、语言特性以及标准库。这些内容教你如何编写具有输入、输出、计算以及简单图形显示等功能的程序。《C++程序设计原理实践(英文版)》第二部分则介绍了一些更专门性的内容(如文本处理和测试),并提供了大量的参考资料。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值