2022级吉林大学面向对象第三次上机测试

【注:解答全部为本人所写,仅供同学们学习时参考使用,请勿照搬抄袭!】

运算符重载、动态内存管理
1.已知字符串类MyString的定义为:

class MyString
{
  public:
	MyString(const char* pData= NULL);		// 普通构造函数
	MyString(const MyString &);	        	// 拷贝构造函数
	~ MyString();					// 析构函数
	MyString & operator =(const MyString &);	// 赋值函数
	MyString& operator += (const MyString &);
	operator char* () const;                 	// 自动转换函数 
  private:
	char  	*mpData;				// 用于保存字符串
   };	

全局函数:
const MyString operator + (const MyString &,const MyString &);//字符串连接
ostream& operator<<(ostream& os, const MyString& str); //定向输出

请完整实现MyString类和指定的全局函数。(可以使用new,delete运算以及strcpy,strlen,…等库函数,还可以定义其他辅助函数)。

#include 
#include 
using namespace std;

class MyString {
friend ostream& operator<<(ostream& os, const MyString& str);
friend const MyString operator+(const MyString &s1,const MyString &s2); 
public:
	MyString(const char* pData = NULL) {
		this->mpData = new char[5];
		strcpy(this->mpData, pData);
	}	// 普通构造函数
	MyString(const MyString &s) {  
		this->mpData = new char[10];
		strcpy(this->mpData, s.mpData);
	}       	// 拷贝构造函数
	~ MyString() { delete this->mpData;}				// 析构函数
	MyString& operator=(const MyString &s) {
		this->mpData = new char[10];
		strcpy(this->mpData, s.mpData);
		return *this;
	}	// 赋值函数
	MyString& operator+=(const MyString &s) {
		int len=strlen(mpData)+strlen(s.mpData)+1;
		char *tmp = new char[len];
		strcpy(tmp, mpData);
		strcat(tmp, s.mpData);
		strcpy(mpData, tmp);
		delete[] tmp;	
		return *this;
	}
	operator char* () const;                 	// 自动转换函数 
private:
	char* mpData;				// 用于保存字符串
};	

const MyString operator+(const MyString &s1,const MyString &s2) {
	return MyString(s1)+=s2;
}//字符串连接    	  
ostream& operator<<(ostream& os, const MyString& str) {
	os << str.mpData << endl;
	return os;
}		//定向输出

int main()
{
	MyString a1("123");
	MyString a2("456");
	MyString c = a1 + a2;
	cout << c << endl;
	return 0;
} 

2.对任意一个正的实数,总可以唯一地表示成a0+1/(a1+1/(a2+1/(a3+1/…)))的形式,简记为a0+a1+a2+a3+…+ak。(ai为大于0 的正整数,长度为k。若数为无理数,则k为无穷大) ,并称这种形式的数为连分数。

a)请使用类的自关联方式设计并实现连分数类, 此类的每个对象代表一个有理数的连分数形式,且假定连分数的长度均小于MAXLEN(MAXLEN设为数30)。
该类主要功能有:
1)对指定的i,返回ai值;
2)计算连分数的前q项(a0+a1+a2+a3+…+aq)所对应分数的分子和分母;
3)输出此分数的前q项,格式为:a0+a1+a2+a3+…+aq;

b)给出主程序,使用该类计算连分数的前n项对应的分数逼近PI值的程度(计算差即可。PI可用math.h中的M_PI常量)。
(由此可见祖老师给出的约率和密率是多么地精确!连分数的收敛速度多么地快!)

例如主程序的输出可能如下:

PI=3.141592653589793

前1项为3
前1项对应分数为3/1
前1项对应分数的值为3
前1项对应分数与3.141592653589793的差为0.1415926535897931

前2项为3+7
前2项对应分数为22/7
前2项对应分数的值为3.142857142857143
前2项对应分数与3.141592653589793的差为-0.001264489267349741

前3项为3+7+15
前3项对应分数为333/106
前3项对应分数的值为3.141509433962264
前3项对应分数与3.141592653589793的差为8.321962752896503e-005

前4项为3+7+15+1
前4项对应分数为355/113
前4项对应分数的值为3.141592920353983
前4项对应分数与3.141592653589793的差为-2.667641891848736e-007

前5项为3+7+15+1+292
前5项对应分数为103993/33102
前5项对应分数的值为3.141592653011902
前5项对应分数与3.141592653589793的差为5.778905119192823e-010

前6项为3+7+15+1+292+1
前6项对应分数为104348/33215
前6项对应分数的值为3.141592653921421
前6项对应分数与3.141592653589793的差为-3.316279286770529e-010

前7项为3+7+15+1+292+1+1
前7项对应分数为208341/66317
前7项对应分数的值为3.141592653467437
前7项对应分数与3.141592653589793的差为1.223564103768754e-010

前8项为3+7+15+1+292+1+1+1
前8项对应分数为312689/99532
前8项对应分数的值为3.141592653618936
前8项对应分数与3.141592653589793的差为-2.914350748575711e-011

前9项为3+7+15+1+292+1+1+1+2
前9项对应分数为833719/265381
前9项对应分数的值为3.141592653581078
前9项对应分数与3.141592653589793的差为8.715344852056051e-012

前10项为3+7+15+1+292+1+1+1+2+1
前10项对应分数为1146408/364913
前10项对应分数的值为3.141592653591404
前10项对应分数与3.141592653589793的差为-1.610862485068587e-012

#include 
#include 
using namespace std;
const int MAXLEN = 30;

class CFraction {
private:
	vector<int> ai; // 存储a0,a1,a2,...,ak
public:
	
	int length() { // 返回连分数的长度
		return ai.size();
	}
	
	void add(int a) { // 添加下一个ai
		ai.push_back(a);
	}
	
	void print(int q) { // 输出连分数的前q项
		cout << ai[0];
		for (int i = 1; i < q; i++) {
			cout << "+" << ai[i];
		}
		cout << endl;
	}
	
	void fraction(int q, int& num, int& den) { // 计算连分数的前q项所对应的分数
		num = ai[q - 1];
		den = 1;
		for (int i = q - 2; i >= 0; i--) {
			int tmp = num;
			num = ai[i] * num + den;
			den = tmp;
		}
	}
};

CFraction getCFraction(double x, int maxLen) { // 将实数转化为连分数
	CFraction cf;
	int a = int(x);
	cf.add(a);
	double r = x - a;
	while (r > 0 && cf.length() < maxLen) {
		r = 1 / r;
		a = int(r);
		cf.add(a);
		r -= a;
	}
	return cf;
}

int main() 
{
	double pi = 3.14159265358979323;
	for (int i = 1; i <= 10; i++) {
		CFraction cf = getCFraction(pi, i);
		int num = 0, den = 0;
		cf.fraction(i, num, den);
		double approx = double(num) / den;
		cout << "前" << i << "项为";
		cf.print(i);
		cout << "前" << i << "项对应分数为" << num << "/" << den << endl;
		cout << "前" << i << "项对应分数的值为" << approx << endl;
		cout << "前" << i << "项对应分数与" << pi << "的差为" << pi - approx << endl << endl;
	}
	return 0;
}

3、在全局函数void f(int n,int m)中动态建立一个大小为nxm的二维整数数组,并对每个数组元素依次赋值为1,2,3,…,m*n, 再输出每行和每列元素的和,退出函数前释放此数组。

#include 
using namespace std;

void f(int n, int m) {
	int ** array = new int* [n];
	for (int i = 0; i < n; i++) {
		array[i] = new int [m];
	}
	int count = 1;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			array[i][j] = count;
			count++;
		}
	}
	for (int i = 0; i < n; i++) {
		int sum = 0;
		for (int j = 0; j < m; j++) {
			sum += array[i][j];
		}
		cout << "Row " << i + 1 << " : sum = " << sum << endl;
	}
	puts("");
	for (int j = 0; j < m; j++) {
		int sum = 0;
		for (int i = 0; i < n; i++) {
			sum += array[i][j];
		}
		cout << "Col " << j + 1 << " : sum = " << sum << endl;
	}
	for (int i = 0; i < n; i++) {
		delete[] array[i];
	}
	delete[] array;
} 

int main()
{
    f(3, 4);
    return 0;
}

4、已有类A声明如下:
class A
{
public:
A(int n):data(n) {}
int Data() const {return data;}
private:
int data;
};
在全局函数void g(int n) 中动态建立一个大小为n的一维指针数组, 数组元素指向A类对象,各对象的data数据成员各不相同, 分别为1,2,3,…,n。创建数组后,使用(例如输出)各对象的data值,最后释放此数组。

#include 
using namespace std;

class A {
public:
    A(int n) : data(n) {}
    int Data() const { 
		return data; 
	}
private:
    int data;
};

void g(int n) {
	A** array = new A*[n];
	for (int i = 0; i < n; i++) {
		array[i] = new A(i + 1);
		cout << array[i]->Data() << endl;
	}
	
	for (int i = 0; i < n; i++) {
		delete[] array[i];
	}
	delete[] array;
}

int main()
{
	g(5);
	return 0;
} 

5、如何建立一个二维整数数组类,使得其大小可动态决定,并且访问时,可像普通数组一样使用。如 建立这个二维整数数组类的一个对象obj后, 访问其第二行、第三列元素,可写成:
obj[1][2] = 5;
cout<

#include 
using namespace std;

class Array{
public:
	Array(int row, int col) {
		m_row = row;
		m_col = col;
		m_data = new int* [m_row];
		for (int i = 0; i < m_row; i++) {
			m_data[i] = new int [m_col];
		}
	}
	
	~Array() {
		for (int i = 0; i < m_row; i++) {
			delete[] m_data[i];
		}
		delete[] m_data;
	}
	
	int* operator[] (int index) {
		return m_data[index];
	}
	
private:
	int m_row;
	int m_col;
	int** m_data;	
};

int main()
{
	Array obj(2, 3);
	obj[1][2] = 2;
	cout << obj[1][2];
	return 0;
}

你可能感兴趣的:(C++面向对象程序设计,c++,算法)