Essential C++--Exercise of Chpt.2

前言

  本文用于记录阅读书籍《Essential C++》Chpt.2后完成课后习题。


正文(Code)

2.1 Continuous Input

  先前的main()只让用户输入一个位置值,然后便结束程序。如果用户想取得两个甚至更多元素值,他必须执行这个程序两次或多次。请改写main(),使它允许用户不断输入位置值,直到用户希望停止为止。

#include <iostream>

using namespace std;

#if 0 
// instance A from template class 
template <Class T1, Class T2> Class A
{
public:
    int a;

    int func_a(T1 a, T2 b);
}

// function func_a definition of class A from template class
template <Class T1, Class T2> int A<T1, T2>::func_a(T1 a ,T2 b)
{
    return (a + b);
}
#endif

void pr_sequence(int idx, int elem)
{
    cout << elem << (!(idx % 10) ? '\n' : ' ');
}

bool fibon_elem(int pos, int & elem)
{
    if (pos <= 0 || pos > 1024)
    {
        cout << "invalid pos[" << pos << "]" << endl;
        return false;
    }

    switch(pos)
    {
        case 2:
        {
            cout << "1 ";
        }
        case 1:
        {
            cout << "1 ";
            break;
        }
        default:
        {
            cout << "1 1 ";
            break;
        }
    }

    int n_1 = 1, n_2 = 1;

    for(int i = 3; i <= pos; i++)
    {
        elem = n_1 + n_2;
        n_1 = n_2;
        n_2 = elem;

        pr_sequence(i, elem);
    }
    cout << endl;
    
    return true;
}

bool usr_try_query(void)
{
    bool b_usr_try = false;
    char c_usr_ipt = false;
    
    cout << "try it? (Y/y: yes, N/n: no): ";
    cin >> c_usr_ipt;

    if ('Y' == c_usr_ipt || 'y' == c_usr_ipt)
    {
        b_usr_try = true;
    }
    else
    {
        b_usr_try = false;

        if ('N' != c_usr_ipt && 'n' != c_usr_ipt)
        {
            cout << "invalid input character[" << c_usr_ipt << "]" << endl;
        }
    }

    return b_usr_try;
}

int get_usr_pos(void)
{
    int i_usr_pos = 0;
    
    cout << "pls input a pos(1~1024): ";
    cin >> i_usr_pos;
    cout << endl;

    return i_usr_pos;
}

int main()
{
    int i_pos;
    int i_elem;
    
    while(usr_try_query())
    {
        i_pos = get_usr_pos();
        
        if (false == fibon_elem(i_pos, i_elem))
        {
            cout << "cal fibon elem failed!" << endl;
            continue;
        }

        cout << "get fibon elem[" << i_elem << "]" << endl;
    }

    cout << "usr exit" << endl;
    return 0;
}

2.2 List Pentagonal

  Pentagonal数列的求值公式是:
P ( n ) = n ( 3 n − 1 ) / 2 P(n) = n(3n-1)/2 P(n)=n(3n1)/2
  借此产生1, 5, 12, 22, 35等元素值。试定义一个函数,利用上述公式,将产生的元素放到用户传入的vector之中,元素个数由用户指定。请检查元素个数的有效性(太大则可能引发overflow问题)。接下来编写第二个函数,能够将给定的vector的所有元素一一打印出来。此函数的第二参数接受一个字符串,表示存放在vector内的数列的类型。最后再写一个main(),测试上述两个函数。

#include <iostream>
#include <vector>
#include <string>

using namespace std;

bool is_num_valid(int num)
{
    return !(num <= 0 || num > 1024);
}

int get_penta_val(int num, vector<int> &v_store)
{
    if (true != is_num_valid(num))
    {
        cout << "invalid num: " << num << endl;
        return -1;
    }

    if (num <= v_store.size())
    {
        cout << "already ok!" << endl;
        return 0;
    }

    for(int i = v_store.size()+1; i <= num; i++)
    {
        v_store.push_back(i * (3 * i - 1) / 2);
    }
    
    return 0;    
}

void pr_usr_vector(vector<int> &vec, string &type)
{
    cout << "vector type: " << type << endl;

    for(int i = 0; i < vec.size(); i++)
    {
        cout << vec.at(i) << ((9 == i % 10) ? '\n' : ' ');
    }
    cout << endl;
    
    return;
}

bool get_another_try(void)
{
    bool bTry = false;
    char cUsrIpt = 0;

    cout << "Try it? (Y/y: yes  N/n: no): ";
    cin >> cUsrIpt;

    if ('Y' == cUsrIpt || 'y' == cUsrIpt)
    {
        bTry = true;
    }
    else
    {
        bTry = false;

        if ('N' != cUsrIpt && 'n' != cUsrIpt)
        {
            cout << "invalid input[" << cUsrIpt << "]" << endl;
        }
    }
   
    return bTry;
}

int get_usr_input_num(int &num)
{
    cout << "pls input num(1~1024): ";
    cin >> num;

    if (num <= 0 || num > 1024)
    {
        cout << "invalid input num: " << num << endl;
        return -1;
    }

    cout << "get input num: " << num << endl;
    return 0;
}

int main()
{
    static vector<int> v_usr;
    int i_usr_input = 0;
    string str_type("string");

    while(get_another_try())
    {
        if (0 != get_usr_input_num(i_usr_input))
        {
            continue;
        }
        
        if (0 != get_penta_val(i_usr_input, v_usr))
        {
            cout << "update user vector failed!" << endl;
            return -1;
        }

        pr_usr_vector(v_usr, str_type);
    }

    cout << "usr exit" << endl;
    return 0;
}

2.3 Split Pentagonal List

  将练习2.2的Pentagonal数列求值函数拆分为两个函数,其中之一为inline,用来检验元素个数是否合理。如果的确合理,而且尚未被计算,便执行第二个函数,执行实际的求值工作。

#include <iostream>
#include <vector>
#include <string>

#include "2.3.h"     // header file

using namespace std;

bool is_num_valid(int num)
{
    return !(num <= 0 || num > 1024);
}

int get_penta_val(int num, vector<int> &v_store)
{
    if (true != is_num_valid(num))
    {
        cout << "invalid num: " << num << endl;
        return -1;
    }

    if (num <= v_store.size())
    {
        cout << "already ok!" << endl;
        return 0;
    }

    for(int i = v_store.size()+1; i <= num; i++)
    {
        v_store.push_back(i * (3 * i - 1) / 2);
    }
    
    return 0;    
}

void pr_usr_vector(vector<int> &vec, string &type)
{
    cout << "vector type: " << type << endl;

    for(int i = 0; i < vec.size(); i++)
    {
        cout << vec.at(i) << ((9 == i % 10) ? '\n' : ' ');
    }
    cout << endl;
    
    return;
}

bool get_another_try(void)
{
    bool bTry = false;
    char cUsrIpt = 0;

    cout << "Try it? (Y/y: yes  N/n: no): ";
    cin >> cUsrIpt;

    if ('Y' == cUsrIpt || 'y' == cUsrIpt)
    {
        bTry = true;
    }
    else
    {
        bTry = false;

        if ('N' != cUsrIpt && 'n' != cUsrIpt)
        {
            cout << "invalid input[" << cUsrIpt << "]" << endl;
        }
    }
   
    return bTry;
}

int main()
{
    static vector<int> v_usr;
    int i_usr_input = 0;
    string str_type("string");

    while(get_another_try())
    {
        if (0 != get_usr_input_num(i_usr_input))
        {
            continue;
        }
        
        if (0 != get_penta_val(i_usr_input, v_usr))
        {
            cout << "update user vector failed!" << endl;
            return -1;
        }

        pr_usr_vector(v_usr, str_type);
    }

    cout << "usr exit" << endl;
    return 0;
}

  头文件如下:

#ifndef _2_3_H_
#define _2_3_H_

#include <iostream>

using namespace std;

inline int get_usr_input_num(int &num)
{
    cout << "pls input num(1~1024): ";
    cin >> num;

    if (num <= 0 || num > 1024)
    {
        cout << "invalid input num: " << num << endl;
        return -1;
    }

    cout << "get input num: " << num << endl;
    return 0;
}

#endif

2.4 Split Pentagonal List_V2

  写一个函数,以局部静态(local static)vector储存Pentagonal数列元素。此函数返回一个const指针,指向该vector。如果vector的大小小于指定的元素个数,就扩充vector的大小。接下来再实现第二个函数,接受一个位置值,返回该位置上的元素。最后,编写main()测试这些函数。
  注:包含的头文件参考2.3小节。

#include <iostream>
#include <vector>
#include <string>

#include "2.3.h"     // header file

using namespace std;

bool is_num_valid(int num)
{
    return !(num <= 0 || num > 1024);
}

const vector<int> *get_vec(int num)
{
    static vector<int> vec;
    
    if (num <= vec.size())
    {
        cout << "already ok!" << endl;
        return &vec;  
    }

    for(int i = vec.size()+1; i <= num; i++)
    {
        vec.push_back(i * (3 * i - 1) / 2);
    }
    
    return &vec;    
}

void pr_usr_vector(const vector<int> &vec, string &type)
{
    cout << "vector type: " << type << endl;

    for(int i = 0; i < vec.size(); i++)
    {
        cout << vec.at(i) << ((9 == i % 10) ? '\n' : ' ');
    }
    cout << endl;
    
    return;
}

bool get_another_try(void)
{
    bool bTry = false;
    char cUsrIpt = 0;

    cout << "Try it? (Y/y: yes  N/n: no): ";
    cin >> cUsrIpt;

    if ('Y' == cUsrIpt || 'y' == cUsrIpt)
    {
        bTry = true;
    }
    else
    {
        bTry = false;

        if ('N' != cUsrIpt && 'n' != cUsrIpt)
        {
            cout << "invalid input[" << cUsrIpt << "]" << endl;
        }
    }
   
    return bTry;
}

int main()
{
    const vector<int> *pv_usr = 0;
    int i_usr_input = 0;
    string str_type("string");

    while(get_another_try())
    {
        if (0 != get_usr_input_num(i_usr_input))
        {
            continue;
        }

        if (true != is_num_valid(i_usr_input))
        {
            cout << "invalid num: " << i_usr_input << endl;
            continue;
        }
        
        pv_usr = 0;
        if (!(pv_usr = get_vec(i_usr_input)))
        {
            cout << "update user vector failed!" << endl;
            return -1;
        }

        pr_usr_vector(*pv_usr, str_type);
    }

    cout << "usr exit" << endl;
    return 0;
}

2.5 First Meeting with Overload

  实现一个重载的max()函数,让它接受以下参数:(a)两个整数,(b)两个浮点数,(c)两个字符串,(d)一个整数vector,(f)一个字符串vector,(g)一个整数数组,以及一个表示数组大小的整数值,(h)一个浮点数数组,以及一个表示数组大小的整数值,(i)一个字符串数组,以及一个表示数组大小的整数值。最后编写main()测试这些函数。

#include <iostream>
#include <string>
#include <vector>

using namespace std;

int max(int a, int b)
{
    cout << "func: int + int" << endl;
    cout << "get max: " << (a < b ? b : a) << endl;
    
    return 0;
}

int max(float a, float b)
{
    cout << "func: float + float" << endl;
    cout << "get max: " << (a < b ? b : a) << endl;
    
    return 0;
}

int max(string a, string b)
{
    cout << "func: string + string" << endl;
    cout << "get max: " << (a < b ? b : a) << endl;
    
    return 0;
}

int max(vector<int> &vec)
{
    cout << "func: vector<int>" << endl;

    if (vec.empty())
    {
        cout << "vector empty!" << endl;
        return 0;
    }

    int i_max = vec.at(0);
    for(int i = 1; i < vec.size(); i++)
    {
        i_max = i_max < vec.at(i) ? vec.at(i) : i_max;
    }
    
    cout << "get max: " << i_max << endl;
    
    return 0;
}

int max(vector<float> &vec)
{
    cout << "func: vector<float>" << endl;

    if (vec.empty())
    {
        cout << "vector empty!" << endl;
        return 0;
    }

    float f_max = vec.at(0);
    for(int i = 1; i < vec.size(); i++)
    {
        f_max = f_max < vec.at(i) ? vec.at(i) : f_max;
    }
    
    cout << "get max: " << f_max << endl;
    
    return 0;
}

int max(vector<string> &vec)
{
    cout << "func: vector<string>" << endl;

    if (vec.empty())
    {
        cout << "vector empty!" << endl;
        return 0;
    }

    string str_max = vec.at(0);
    for(int i = 1; i < vec.size(); i++)
    {
        str_max = str_max < vec.at(i) ? vec.at(i) : str_max;
    }
    
    cout << "get max: " << str_max << endl;
    
    return 0;
}

int max(int (&arr)[2], int num)
{
    cout << "func: int array + int" << endl;

    if (0 == num)
    {
        cout << "array empty!" << endl;
        return 0;
    }
    
    int i_max = arr[0];
    for(int i = 1; i < num; i++)
    {
        i_max = i_max < arr[i] ? arr[i] : i_max;
    }
    
    cout << "get max: " << i_max << endl;
    
    return 0;
}

int max(float (&arr)[2], int num)
{
    cout << "func: float array + int" << endl;

    if (0 == num)
    {
        cout << "array empty!" << endl;
        return 0;
    }
    
    float f_max = arr[0];
    for(int i = 1; i < num; i++)
    {
        f_max = f_max < arr[i] ? arr[i] : f_max;
    }
    
    cout << "get max: " << f_max << endl;
    
    return 0;
}

int max(string (&arr)[2], int num)
{
    cout << "func: string array + int" << endl;

    if (0 == num)
    {
        cout << "array empty!" << endl;
        return 0;
    }
    
    string str_max = arr[0];
    for(int i = 1; i < num; i++)
    {
        str_max = str_max < arr[i] ? arr[i] : str_max;
    }
    
    cout << "get max: " << str_max << endl;
    
    return 0;
}

enum func_idx
{
    int_int,
    float_float,
    string_string,
    vec_int,
    vec_float,
    vec_string,
    arr_int,
    arr_float,
    arr_string,
};

int get_func_idx(int &idx)
{
    cout << "pls input your choice: ";
    cin >> idx;

    if (idx < int_int || idx > arr_string)
    {
        cout << "invalid input[" << idx << "]" << endl;
        return -1;
    }
    
    return 0;
}

bool try_another_one(void)
{
    char c_ipt = 0;
    bool b_try = 0;
    
    cout << "try it? (Y/y: yes  N/n: no): ";
    cin >> c_ipt;

    if ('Y' == c_ipt || 'y' == c_ipt)
    {
        b_try = true;
    }
    else
    {
        b_try = false;

        if ('N' != c_ipt && 'n' != c_ipt)
        {
            cout << "invalid input: " << c_ipt;
        }
    }
    
    return b_try;
}

int main()
{
    int idx = 0;
    while(try_another_one())
    {
        if (0 != get_func_idx(idx))
        {
            continue;
        }

        switch(idx)
        {
            case int_int:
            {
                max((int)2,(int)3);
                break;
            }
            case float_float:
            {
                max((float)2.1,(float)3.2);
                break;
            }
            case string_string:
            {
                string str1("test!");
                string str2("yeah!");

                max(str1,str2);
                break;
            }
            case vec_int:
            {
                vector<int> vec_1;

                vec_1.push_back(2);
                vec_1.push_back(3);
                
                max(vec_1);
                break;
            }
            case vec_float:
            {
                vector<float> vec_2;

                vec_2.push_back(2.1);
                vec_2.push_back(3.2);
                
                max(vec_2);
                break;
            }
            case vec_string:
            {
                vector<string> vec_3;

                vec_3.push_back("test!");
                vec_3.push_back("yeah!");
                
                max(vec_3);
                break;
            }
            case arr_int:
            {
                int arr_1[2] = {2, 3};

                max(arr_1, 2);
                break;
            }
            case arr_float:
            {
                float arr_2[2] = {2.1, 3.2};

                max(arr_2, 2);
                break;
            }
            case arr_string:
            {
                string arr_3[2] = {"test!", "yeah!"};

                max(arr_3, 2);
                break;
            }
        }
    }

	cout << "user exit!" << endl;
	
    return 0;
}

2.6 Retry with Template Function

  以template重新完成练习2.5,并对main()函数做适度的修改。

#include <iostream>
#include <string>
#include <vector>

using namespace std;

template <typename T>
int max(T &a, T &b)
{
	cout << "get max: " << (a < b ? b : a) << endl;  
	return 0;
}

template <typename T>
int max(vector<T> &vec)
{
    cout << "func: vector<string>" << endl;

    if (vec.empty())
    {
        cout << "vector empty!" << endl;
        return 0;
    }

    T t_max = vec.at(0);
    for(int i = 1; i < vec.size(); i++)
    {
        t_max = t_max < vec.at(i) ? vec.at(i) : t_max;
    }
    
    cout << "get max: " << t_max << endl;
    
    return 0;
}

template <typename T>
int max(T (&arr)[2], int num)
{
    cout << "func: string array + int" << endl;

    if (0 == num)
    {
        cout << "array empty!" << endl;
        return 0;
    }
    
    T t_max = arr[0];
    for(int i = 1; i < num; i++)
    {
        t_max = t_max < arr[i] ? arr[i] : t_max;
    }
    
    cout << "get max: " << t_max << endl;
    
    return 0;
}

enum func_idx
{
    int_int,
    float_float,
    string_string,
    vec_int,
    vec_float,
    vec_string,
    arr_int,
    arr_float,
    arr_string,
};

int get_func_idx(int &idx)
{
    cout << "pls input your choice: ";
    cin >> idx;

    if (idx < int_int || idx > arr_string)
    {
        cout << "invalid input[" << idx << "]" << endl;
        return -1;
    }
    
    return 0;
}

bool try_another_one(void)
{
    char c_ipt = 0;
    bool b_try = 0;
    
    cout << "try it? (Y/y: yes  N/n: no): ";
    cin >> c_ipt;

    if ('Y' == c_ipt || 'y' == c_ipt)
    {
        b_try = true;
    }
    else
    {
        b_try = false;

        if ('N' != c_ipt && 'n' != c_ipt)
        {
            cout << "invalid input: " << c_ipt;
        }
    }
    
    return b_try;
}

int main()
{
    int idx = 0;
    while(try_another_one())
    {
        if (0 != get_func_idx(idx))
        {
            continue;
        }

        switch(idx)
        {
            case int_int:
            {
				int a = 2;
				int b = 3;
                max(a,b);
                break;
            }
            case float_float:
            {
				float a_1 = 2.1;
			    float b_1 = 3.2;

                max(a_1, b_1);
                break;
            }
            case string_string:
            {
                string str1("test!");
                string str2("yeah!");

                max(str1,str2);
                break;
            }
            case vec_int:
            {
                vector<int> vec_1;

                vec_1.push_back(2);
                vec_1.push_back(3);
                
                max(vec_1);
                break;
            }
            case vec_float:
            {
                vector<float> vec_2;

                vec_2.push_back(2.1);
                vec_2.push_back(3.2);
                
                max(vec_2);
                break;
            }
            case vec_string:
            {
                vector<string> vec_3;

                vec_3.push_back("test!");
                vec_3.push_back("yeah!");
                
                max(vec_3);
                break;
            }
            case arr_int:
            {
                int arr_1[2] = {2, 3};

                max(arr_1, 2);
                break;
            }
            case arr_float:
            {
                float arr_2[2] = {2.1, 3.2};

                max(arr_2, 2);
                break;
            }
            case arr_string:
            {
                string arr_3[2] = {"test!", "yeah!"};

                max(arr_3, 2);
                break;
            }
        }
    }

	cout << "user exit!" << endl;
	
    return 0;
}

结语

  个人阅读书籍《Essential C++》之余创建此专栏,用于记录完成每一章节后附录的exercise。如有问题,请各位不吝指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值