C++程序设计 练习题2

1. 类中的构造函数和析构函数可以重载吗?说明原因。

        构造函数可以,因为可以改变参数个数和类型,符合函数重载的要求;

        析构函数不可以,因为参数只有一个固定类型的this,故不可能重载;

2. 分析下面程序的运行结果。

class A {
    int a;
public:
    A(int a): a(a) { printf("A%d",a); }
    A(): a(0) { printf("A%d",a); }
    ~A() { printf("~A%d",a); }
} a(1);

class B {
    int b;
    A a1,a2;
public:
    B(int b): a1(2),b(b) { printf("B%d",b); }
    ~B() { printf("~B%d",b); }
} b(9);

int main() { }

输出:A1A2A0B9~B9~A0~A2~A1

3. 下面的类将N进制整数字符串s转换为M进制的字符串,请完成各个成员函数。测试程序为:

int main() { NumString s("A4",16); printf("%s %s", s.toString(10), s.toString(2)); }
class NumString {
	const char *s;	    //s[]为N进制整数字符串(字母都是大写),如"9AB6"(N=16)
	const int N;		//2 <= N <= 16
	int  decNum; 	//在构造函数中,将s[]转换为10进制数保存到该变量
public:
	NumString(const char *s, int N=10);  //构造函数, s[]是N进制整数字符串,含有大小写字母
	~NumString( );	  //析构函数
	char *toString(int M); //将s[]中的N进制字符串转换为M进制字符串,返回M进制字符串的首地址
private:
	void toNum( );  //将s[]中的N进制整数字符串转换为10进制数并保存到decNum
};

解答:

#include <cmath>
#include <cstdio>
class NumString {
    const char* s;     // s[]为N进制整数字符串(字母都是大写),如"9AB6"(N=16)
    const int N;       // 2 <= N <= 16
    int decNum;        // 在构造函数中,将s[]转换为10进制数保存到该变量

public:
    NumString(const char* s, int N = 10);  // 构造函数, s[]是N进制整数字符串,含有大小写字母
    ~NumString();                             // 析构函数
    char* toString(int M);                   // 将s[]中的N进制字符串转换为M进制字符串,返回M进制字符串的首地址

private:
    void toNum();  // 将s[]中的N进制整数字符串转换为10进制数并保存到decNum
};

NumString::NumString(const char* s, int N) : s(s), N(N) {
    toNum();
}

NumString::~NumString() {
}

char* NumString::toString(int M) {
    int maxLen =(int) (log(decNum) / log(M)) + 2;
    char* result = new char[maxLen];

    int quot = decNum;
    int i = 0;

    while (quot > 0) {
        int remainder = quot % M;
        result[i++] = (remainder < 10) ? remainder + '0' : remainder - 10 + 'A';
        quot /= M;
    }
    
    if (i == 0) {
        result[i++] = '0';
    }
    
    for (int j = 0; j < i / 2; j++) {
        char tmp = result[j];
        result[j] = result[i - j - 1];
        result[i - j - 1] = tmp;
    }

    result[i] = '\0';

    return result;
}

void NumString::toNum() {
    decNum = 0;
    int i = 0;
    //printf("%s\n", s);
    //printf("%d\n", N);
    while (s[i]) {
        int digit = 0;
        if (s[i] >= '0' && s[i] <= '9') {
            digit = s[i] - '0';
        }
        else if (s[i] >= 'A' && s[i] <= 'F') {
            digit = s[i] - 'A' + 10;
        }
        else if (s[i] >= 'a' && s[i] <= 'f') {
            digit = s[i] - 'a' + 10;
        }

        decNum = decNum * N + digit;
        //printf("%c %d %d\n", s[i], digit, decNum);
        i++;
    }
    
}

int main() {
    NumString s("A4", 16);
    printf("%s %s", s.toString(10), s.toString(2));

    return 0;
}

4. 集合类的头文件set.h如下,请定义其中的函数成员。

class SET { 
    int *set; 			//set用于存放集合元素 
    int card; 			//card为能够存放的元素个数 
    int used; 			//used为已经存放的元素个数
    public:
    SET(int card); 		//card为能够存放的元素个数 
    ~SET( );
    int size( ); 			//返回集合已经存放的元素个数 
    int insert(int v); 		//插入v成功时返回1,否则返回0 
    int remove(int v); 	//删除v成功时返回1,否则返回0 
    int has(int v); 		//元素v存在时返回1,否则返回0 
};

解答:

#include<cstdio>

class SET {
        int* set;                         //set用于存放集合元素 
        int card;                         //card为能够存放的元素个数 
        int used;                         //used为已经存放的元素个数
public:
        SET(int card);                 //card为能够存放的元素个数 
        ~SET();
        int size();                         //返回集合已经存放的元素个数 
        int insert(int v);                 //插入v成功时返回1,否则返回0 
        int remove(int v);         //删除v成功时返回1,否则返回0 
        int has(int v);                 //元素v存在时返回1,否则返回0 
        //测试
        void printset();
};

SET::SET(int card) :card(card),used(0) {
        set = new int[card];
}

SET::~SET() {
        delete []set;
}

int SET::size() {
        return used;
}

int SET::insert(int v) {
        if (used == card) {
                return 0;
        }
        if (has(v)) {
                return 0;
        }
        set[used++] = v;
        return 1;
}

int SET::remove(int v) {
        if(used == 0) return 0;
        for (int i = 0; i < used; i++) {
                if (set[i] == v) {
                        set[i] = set[used - 1];
                        used--;
                        return 1;
                }
        }
        return 0;
}

int SET::has(int v) {
        for (int i = 0; i < used; i++) {
                if (set[i] == v) {
                        return 1;
                }
        }
        return 0;
}

void SET::printset() {
        printf("{");
        for (int i = 0; i < used - 1; i++) {
                printf("%d ", set[i]);
        }
        printf("%d", set[used - 1 ]);
        printf("}\n");
}

int main() {
        SET mySet(3);
        mySet.insert(1);
        mySet.printset();
        mySet.insert(1);
        mySet.printset();
        mySet.insert(2);
        mySet.printset();
        mySet.insert(3);
        mySet.printset();
        mySet.insert(4);
        mySet.printset();
        printf("%d \n", mySet.has(3));
}

5. 线性表通常提供元素查找、插入和删除等功能。以下线性表是一个整型线性表,表元素存放在动态申请的内存中,请编程定义整型线性表的函数成员。

class INTLIST { 
    int  *list; 			//动态申请的内存的指针 
    int  size; 			//线性表能够存放的元素个数 
    int  used; 			//线性表已经存放的元素个数
    public: 
    INTLIST(int s); 		//s为线性表能够存放的元素个数 
    int insert(int v); 		//插入元素v成功时返回1,否则返回0 
    int remove(int v); 	//删除元素v成功时返回1,否则返回0 
    int find(int v); 		//查找元素v成功时返回1,否则返回0 
    int get(int k); 		//取表的第k个元素的值作为返回值
    ~INTLIST( ); 
};

解答:

#include<cstdio>

class INTLIST {
        int* list;                         //动态申请的内存的指针 
        int  size;                         //线性表能够存放的元素个数 
        int  used;                         //线性表已经存放的元素个数
public:
        INTLIST(int s);                 //s为线性表能够存放的元素个数 
        int insert(int v);                 //插入元素v成功时返回1,否则返回0 
        int remove(int v);         //删除元素v成功时返回1,否则返回0 
        int find(int v);                 //查找元素v成功时返回1,否则返回0 
        int get(int k);                 //取表的第k个元素的值作为返回值
        void printlist();
        ~INTLIST();
};

INTLIST::INTLIST(int s) : size(s),used(0){
        list = new int [size];
}

INTLIST::~INTLIST() {
        delete [] list;
}

int INTLIST::insert(int v) {
        if (used == size) {
                return 0;
        }
        list[used++] = v;
        return 1;
}

int INTLIST::remove(int v) {
        for (int i = 0; i < used; i++) {
                if (list[i] == v) {
                        for (int j = i; j < used - 1; j++) {
                                list[j] = list[j + 1];
                        }
                        used--;
                        return 1;
                }
        }
        return 0;
}

int INTLIST::find(int v) {
        for (int i = 0; i < used; i++) {
                if (list[i] == v) {
                        return 1;
                }
        }
        return 0;
}

int INTLIST::get(int k) {
        if (k - 1 >= used || k - 1 < 0) {
                printf("wrong index\n");
                return -1;
        }
        return list[k - 1];
}

void INTLIST::printlist() {
        for (int i = 0; i < used - 1; i++) {
                printf("%d ", list[i]);
        }
        printf("%d\n", list[used - 1]);
}


int main() {
        INTLIST mylist(4);
        mylist.insert(1);
        mylist.insert(2);
        mylist.insert(1);
        mylist.insert(3);
        mylist.printlist();
        printf("at 2 is %d\n", mylist.get(2));
        mylist.remove(3);
        mylist.printlist();
        return 0;
}

6. 下面是二叉树类的定义,请完成各个成员函数。

class TREE { 
    int  item; //节点的值
    TREE  *left, *right; //左、右子树
    public:
    TREE(int item); //构造树:item为根节点、左右子树为null
    TREE(int item, TREE *left, TREE *right); //构造树:item为根节点、左右子树为left、right
    ~TREE( ); 
    int  getNodeNum( );	//返回节点总数
    int  getNodes(int items[ ]); //将所有的节点的值保存到items[ ]中
}; 

解答:

#include<cstdio>

class TREE {
        int  item; //节点的值
        TREE* left, * right; //左、右子树
public:
        TREE(int item); //构造树:item为根节点、左右子树为null
        TREE(int item, TREE* left, TREE* right); //构造树:item为根节点、左右子树为left、right
        ~TREE();
        int  getNodeNum();        //返回节点总数
        int getNodeshelper(int items[], int index);
        int  getNodes(int items[]); //将所有的节点的值保存到items[ ]中
};

TREE::TREE(int item) :item(item) {
        left = nullptr;
        right = nullptr;
}

TREE::TREE(int item, TREE* left, TREE* right) :item(item), left(left),right(right){

}

TREE::~TREE() {
        delete left;
        delete right;
}



int TREE::getNodeNum() {
        int nodenum = 1;
        if (left != nullptr) {
                nodenum += left->getNodeNum();
        }
        if (right != nullptr) {
                nodenum += right->getNodeNum();
        }
        return nodenum ;
}

int TREE::getNodes(int items[]) {
        getNodeshelper(items, 0);
        return 1;
}

int TREE::getNodeshelper(int items[], int index) {
        items[index++] = item;
        if (left != nullptr) {
                index = left->getNodeshelper(items, index);
        }
        if (right != nullptr) {
                index = right->getNodeshelper(items, index);
        }
        return index;
}


int main() {
        TREE* leaf1 = new TREE(12);
        TREE* leaf2 = new TREE(81);
        TREE* leaf3 = new TREE(92);
        TREE* leaf4 = new TREE(66);
        TREE* node1 = new TREE(1, leaf1, leaf2);
        TREE* node2 = new TREE(2, leaf3, leaf4);
        TREE* root = new TREE(4, node1, node2);

        int nodeCount = root->getNodeNum();
        printf("nodenum : %d\n", nodeCount);

        int *items = new int [nodeCount];
        root->getNodes(items);

        printf("Nodes: \n");
        for (int i = 0; i < nodeCount; i++) {
                printf("%d ", items[i]);
        }

        delete root;  

        return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值