数据结构、算法与应用C++描述——第一章习题代码

1-1修改后的代码为

//chp1_1
//修改交换函数
void swapChp1(int& x, int& y) 
{
    
    //交换整数x和y
    int temp = x;
    x = y;
    y = temp;
}

1-2编写一个模板函数count,返回值是数组a[0:n-1]中value出现的次数。测试你的代码。

//chp1_2
//编写一个模板函数count,返回值为数组a[0:n-1]中value出现的次数
//函数参数为数组,待查询的值,数组长度
template<class T>
int countChp1_2(T* a, T value, int length) 
{
    
    //返回a中value出现次数
    int count = 0;
    for (int i = 0; i < length; i++) 
    {
    
    
        if (a[i] == value)
        {
    
    
            count++;
        }
    }
    return count;
}

1-3编写一个模板函数fill,给数组a[start:end-1]赋值value。测试你的代码。

//Chp1-3
//编写一个模板函数fill,给数组a[start:end-1]赋值value
//函数参数为数组,要求覆盖的值,开始坐标,结束坐标(不包括)
template<class T>
void fillchp1_3(T* a,T value,int start,int end) 
{
    
    //将a[start:end-1]赋值为value

    for (int i = start; i < end; i++) {
    
    
        a[i] = value;
    }
}

1-4编写一个模板函数inner_product,返回值是 ∑ i = 0 n − 1 a [ i ] ∗ b [ i ] \sum_{i=0}^{n-1}{a[i]*b[i]} i=0n1a[i]b[i]。测试你的代码。

//chp1-4
//编写一个模板函数inner_product,返回值是a[i]*b[i] i从0~n-1
//函数参数为数组a,数组b,n
template<class T>
T inner_product(T* a, T* b, int n) 
{
    
    //求a[i]*b[i] i从0~n-1 的和
    T sum = 0;
    for (int i = 0; i < n; i++) {
    
    
        sum += a[i] * b[i];
    }
    return sum;
}

1-5编写一个模板函数iota,使a[i]=value+i, 0 ≤ i < n 0\leq i<n 0i<n。测试你的代码。

//chp1-5
//编写一个模板函数iota,使a[i]=value+i, 0<= i <n.
//函数参数为数组a,值value,数组长度length
template<class T>
void iota(T* a, T value, int length) 
{
    
    //对a[i]=value+i, 0<= i <n.
    for (int i = 0; i < length; i++) {
    
    
        a[i] = value + i;
    }
}

1-6编写一个模板函数is_sorted,当且仅当a[0:n-1]有序时,返回值是true。测试你的代码。

//chp1-6
//编写一个模板函数is_sorted,当且仅当a[0,n-1]有序时,返回值为true
//函数参数为数组a,数组长度length
template<class T>
bool is_sorted(T* a, int length)
{
    
    //数组有序返回true
    bool flag = true;
    if (a[0] > a[1]) {
    
    
        for (int i = 2; i < length; i++) {
    
    
            if (a[i] > a[i - 1]) {
    
    
                flag = false;
                break;
            }
        }
    }
    else
    {
    
    
        for (int i = 2; i < length; i++)
        {
    
    
            if (a[i] < a[i - 1]) {
    
    
                flag = false;
            }
        }
    }
    return flag;
}

1-7编写一个模板函数mismatch,返回值是使不等式 a [ i ] ≠ b [ i ] a[i]\neq b[i] a[i]=b[i]成立的最小索引i, 0 ≤ i < n 0\leq i<n 0i<n

//chp1-7
//编写模板函数mismatch,返回值为使不等式a[i]不等于b[i]成立的最小索引
//函数参数数组a,数组b,数组长度
template<class T>
int mismatch(T* a, T* b, int length) {
    
    
    for (int i = 0; i < length; i++) {
    
    
        if (a[i] != b[i]) {
    
    
            return i;
        }
    }
    return -1;
}

1-10修改程序例1-8,使抛出的异常类型是整形。如果a、b、c都小于0,那么抛出的异常值是1,如果a、b、c都等于0,那么抛出的异常值是2,。否则没有异常

//chp1-10
//修改程序例1-8,使抛出的异常类型是整形。如果a、b、c都小于0,那么抛出的异常值是1,如果a、b、c都等于0,那么抛出的异常值是2,。否则没有异常
//函数参数三个整形
int abc(int a, int b, int c) {
    
    
    if (a < 0 || b < 0 || c < 0)
        throw 1;
    else if (a == 0 || b == 0 || c == 0)
        throw 2;
    return a + b * c;
}

1-11重做练习2。不过,当n<1时,抛出类型为char*的异常。测试你的代码。

// chp1_11
//修改练习2,当n<1时,抛出类型为char* 的异常
//函数参数为数组,待查询的值,数组长度
template<class T>
int countChp1_11(T * a, T value, int length)
{
    
    //返回a中value出现次数
    if (length < 1)
        throw "The arrays length must be >= 1";
    int count = 0;
    for (int i = 0; i < length; i++)
    {
    
    
        if (a[i] == value)
        {
    
    
            count++;
        }
    }
    return count;
}

1-12.为程序make2dArray编写一个通用型算法,他的第三个参数不是整数numberOfColumns,而是一位数组rowSize.他创建一个二维数组,第i行的列数是rowSize[i]

/*
    12.为程序make2dArray编写一个通用型算法,他的第三个参数不是整数numberOfColumns,而是一位数组rowSize.他创建一个二维数组,第i行的列数是rowSize[i]
    函数参数 表示二维数组的二维指针,行数numberOfRows,列数数组rowSize
*/
template<class T>
bool make2dArray(T**& x, int numberOfRows, int rowSize[]) {
    
    

    x = new T * [numberOfRows];
    for (int i = 0; i < numberOfRows; i++) {
    
    
        x[i] = new T[rowSize[i]];
    }
    return true;

}

template<class T>
void delete2dArray(T**& x, int numberOfRows) {
    
    

    for (int i = 0; i < numberOfRows; i++) {
    
    
        delete[] x[i];
    }

    delete[] x;
    x = NULL;
}

1-13编写一个模板函数changeLength1D,他将一个一维数组的长度从oldLength变成newLength。函数首先分配一个新的、长度为newlength的数组,然后把原数组的前min{oldLength,newLength}个元素复制到新数组中,最后释放原数组所占用的空间。测试你的代码。

注意,我这里用的是比较笨的办法,因为涉及到底层内存的分布,使用new出来的数组会在堆内存上分布,这时使用sizeof(arr)/sizeof(arr[0])是获取不到数组长度的,使用普通数组声明时会在栈内存中分布,此时可以使用该方法来获得数组长度,我这里绕不开就在函数中多加了一个参数,如果有其他好的方法,可以评论告诉我,谢谢各位大佬交流经验

template<class T>
T* changeLength1D(T* &x, int oldLength,int newLength) {
    
    
    if (newLength < 1)
        return NULL;           
    int* tx = new int[newLength]();
    for (int i = 0; i < min(oldLength,newLength); i++) {
    
               //将原数组前min{oldLength,newLength}个元素复制到新数组
       tx[i] = x[i];
    }
    
    delete[] x;
    x = NULL;
    return tx;
}

1-14编写一个函数changeLength2D,它改变一个二维数组的大小,测试你的代码

这里我偷了个懒,调用之前写好的函数。

template<class T>
T** changeLength2D(T**& x, int oldLengthOfRow, int oldsizeCol[],int newLengthOfRow,int newsizeCol[]) {
    
    
    int** newX;
    make2dArray(newX, newLengthOfRow, newsizeCol);

    for (int i = 0; i < min(oldLengthOfRow, newLengthOfRow); i++) {
    
    
        for (int j = 0; j < min(oldsizeCol[i], newsizeCol[i]); j++) {
    
    
            newX[i][j] = x[i][j];
        }
    }

    delete2dArray(x, oldLengthOfRow);
    return newX;
}

1-16扩展程序1-13的类currency,添加下列成员函数:
1)input()从标准输入流中读取currency的值,然后赋给调用对象。
2)subtract(x)从调用对象中减去参数对象x的值,然后赋给调用对象。
3)percent(x)返回一个currency类对象,它的值是调用对象的x%。x的数据类型为double。
4)multiply(x)返回一个currency类对象,它的值是调用对象和double型数x的乘积。
5)divide(x)返回一个currency类的对象,它的值是调用对象除以double型数x的结果。
实现所有成员函数,用适当的数据检验他们正确性。

currency_16.h

#ifndef CURRENCY_16_H
#define CURRENCY_16_H

#include<iostream>
#include"illegalParameterValue.h"
#include"signType.h"


class currency_16
{
    
    
public:
	currency_16(signType theSign = plusc,
		unsigned long theDollars = 0,
		unsigned int theCents = 0
	);       //默认构造函数
	~currency_16() {
    
     }
	void setValue(signType, unsigned long, unsigned int);
	void setValue(double);

	signType getSign() const {
    
    
		return sign_1;
	}

	unsigned long getDollars() const {
    
    
		return dollars;
	}

	unsigned int getCents() const {
    
    
		return cents;
	}
	
	currency_16 add(const currency_16&) const;
	currency_16 sub(const currency_16&) const;
	currency_16 percent(double) const;
	currency_16 multiply(double) const;
	currency_16 divide(double) const;
		 
	currency_16& increment(const currency_16&);
	currency_16& substract(const currency_16&);

	void output()const;
	void input();



private:
	signType sign_1;
	unsigned long dollars;
	unsigned int cents;
};

#endif // !CURRENCY16_H




currency_16.cpp

#include "currency_16.h"



currency_16::currency_16(signType theSign, unsigned long theDollars, unsigned int theCents) {
    
    
	//有参构造函数
	setValue(theSign, theDollars, theCents);
}

void currency_16::setValue(signType theSign, unsigned long theDollars, unsigned int theCents) {
    
    
	if (theCents > 99)
		throw illegalParameterValue("Cents should be < 100");
	sign_1 = theSign;
	dollars = theDollars;
	cents = theCents;
}

void currency_16::setValue(double theAmount) {
    
    
	if (theAmount < 0) {
    
    
		sign_1 = minusc;
		theAmount = -theAmount;
	}
	else
		sign_1 = plusc;
	dollars = (unsigned long)theAmount;
	cents = (unsigned int)((theAmount + 0.001 - dollars) * 100);
	//取两个十位数
}

currency_16 currency_16::add(const currency_16& x)const {
    
    
	//将x 和 this相加 
	long a1, a2, a3;
	currency_16 result;
	a1 = dollars * 100 + cents;
	if (sign_1 == minusc)
		a1 = -a1;
	a2 = x.dollars * 100 + x.cents;
	if (x.sign_1 == minusc)
		a2 = -a2;

	a3 = a1 + a2;
	if (a3 < 0) {
    
    
		result.sign_1 = minusc;
		a3 = -a3;
	}
	else
		result.sign_1 = plusc;

	result.dollars = a3 / 100;
	result.cents = a3 - result.dollars * 100;

	return result;
}

currency_16 currency_16::sub(const currency_16& x)const {
    
    
	//将x 和 this相加 
	long a1, a2, a3;
	currency_16 result;
	a1 = dollars * 100 + cents;
	if (sign_1 == minusc)
		a1 = -a1;
	a2 = x.dollars * 100 + x.cents;
	if (x.sign_1 == minusc)
		a2 = -a2;

	a3 = a1 - a2;
	if (a3 < 0) {
    
    
		result.sign_1 = minusc;
		a3 = -a3;
	}
	else
		result.sign_1 = plusc;

	result.dollars = a3 / 100;
	result.cents = a3 - result.dollars * 100;

	return result;
}

currency_16 currency_16::percent(double x) const {
    
    
	long a1, a2;
	currency_16 result;
	a1 = dollars * 100 + cents;
	if (sign_1 == minusc)
		a1 = -a1;
	a2 = (x+0.001)*100;
	long a = a1 / a2;
	long num = (a1 - a * a2)/100;
	result.sign_1 = plusc;
	result.dollars = num;
	result.cents = a1-a*a2 - result.dollars*100;
	return result; 
}

currency_16 currency_16::multiply(double x) const
{
    
    
	currency_16 result;
	long a1 = this->dollars * 100 + this->cents;
	long a2 = x * 100;
	if (this->sign_1 == minusc)
		a1 = -a1;
	long a3 = a1 * a2;
	result.sign_1 = (a3 < 0) ? minusc : plusc;
	result.dollars = a3 / 10000;
	result.cents = (a3 - result.dollars * 10000)/100;
	return result;
}

currency_16 currency_16::divide(double x) const
{
    
    
	currency_16 result;
	long a1 = this->dollars * 100 + this->cents;
	long a2 = x * 100;
	if (this->sign_1 == minusc)
		a1 = -a1;
	double a3 = (double) a1 / a2;
	result.sign_1 = (a3 < 0)?minusc:plusc;
	result.dollars = a3;
	result.cents = a3 * 100 - result.dollars * 100;
	return result;
}

currency_16& currency_16::increment(const currency_16& x) {
    
    
	*this = add(x);
	return *this;
}


currency_16& currency_16::substract(const currency_16& x) {
    
    
	*this = sub(x);
	return *this;
}

void currency_16::output() const {
    
    
	if (sign_1 == minusc)
		cout << '-';
	cout << '$' << dollars << '.';
	if (cents < 10)
		cout << '0';
	cout << cents;
}

void currency_16::input()
{
    
    
	cout << "Please enter the type of sign dollars and cents:" << endl;
	signType theSigh;
	unsigned long theDollars;
	unsigned int theCents;

	char temp;
	double tempMoney;
	scanf("%c%lf", &temp,&tempMoney);
	if (temp == '-')
		theSigh = minusc;
	else
		theSigh = plusc;
	//枚举类型不能使用cin
	
	theDollars = tempMoney;
	theCents = tempMoney * 100 - theDollars * 100;

	setValue(theSigh, theDollars, theCents);

}

17.使用程序1-19的代码完成练习16.
currency1_17.h

#ifndef CURRENCY_17_H
#define CURRENCY_17_H

#include<iostream>
#include"illegalParameterValue.h"
#include"signType.h"


class currency_17
{
    
    
public:
	currency_17(signType theSign = signType::plusc,
		unsigned long theDollars = 0,
		unsigned int theCents = 0
	);       //默认构造函数
	~currency_17() {
    
     }

	void setValue(signType, unsigned long, unsigned int);
	void setValue(double);

	signType getSign() const {
    
    
		if (amount < 0)
			return signType::minusc;
		else
			return signType::plusc;
	}

	unsigned long getDollars() const {
    
    
		if (amount < 0)
			return (-amount) / 100;
		else
			return amount / 100;
	}

	unsigned int getCents() const {
    
    
		if (amount < 0)
			return -amount - getDollars() * 100;
		else
			return amount - getDollars() * 100;
	}

	currency_17 add(const currency_17& x) const;
	currency_17 sub(const currency_17& x) const;
	currency_17 percent(double) const;
	currency_17 multiply(double) const;
	currency_17 divide(double) const;



	currency_17& increment(const currency_17& x) {
    
    
		amount += x.amount;
		return *this;
	}
	currency_17& substract(const currency_17& x) {
    
    
		amount -= x.amount;
		return *this;
	}

	void output()const;
	void input();



private:
	long amount;
};

#endif // !CURRENCY_17_H

currency1_17.cpp

#include "currency_17.h"



currency_17::currency_17(signType theSign, unsigned long theDollars, unsigned int theCents) {
    
    
	//有参构造函数
	setValue(theSign, theDollars, theCents);
}

void currency_17::setValue(signType theSign, unsigned long theDollars, unsigned int theCents) {
    
    
	if (theCents > 99)
		throw illegalParameterValue("Cents should be < 100");
	amount = theDollars * 100 + theCents;
	if (theSign == signType::minusc)
		amount = -amount;
}

void currency_17::setValue(double theAmount) {
    
    
	if (theAmount < 0)
		amount = (long)((theAmount - 0.001) * 100);
	else
		amount = (long)((theAmount + 0.001) * 100);
	//取两个十位数
}

currency_17 currency_17::add(const currency_17& x) const
{
    
    
	currency_17 y;
	y.amount = amount + x.amount;
	return y;
}

currency_17 currency_17::sub(const currency_17& x) const
{
    
    
	currency_17 y;
	y.amount = amount - x.amount;
	return y;
}

currency_17 currency_17::percent(double x) const
{
    
    
	currency_17 result;
	long a1 = amount;
	long a2 = (x + 0.001) * 100;
	long a = (long)a1 / a2;
	result.amount = amount - a*a2;
	return result;
}


currency_17 currency_17::multiply(double x) const
{
    
    
	currency_17 result;
	result.amount = x * this->amount;
	return result;
}

currency_17 currency_17::divide(double x) const
{
    
    
	currency_17 result;
	long a1 = this->amount;
	double a3 = (double)a1 / x;
	result.amount = a3;
	return result;
}



void currency_17::output() const
{
    
    
	long theAmount = amount;
	if (theAmount < 0) {
    
    
		cout << '-';
		theAmount = -theAmount;
	}
	long dollars = theAmount / 100;
	cout << '$' << dollars << '.';
	int cents = theAmount - dollars * 100;
	if (cents < 10) cout << '0';
	cout << cents;
	cout << endl;
}

void currency_17::input()
{
    
    
	cout << "Please enter the type of sign dollars and cents:" << endl;
	double temp;
	cin >> temp;
	setValue(temp);
}

1)使用程序1-22完成练习16。重载>>、-、%、*、和/。当重载>>时,将其声明为友元函数,不要定义共有输入函数来支持输入操作。
2)重载赋值操作符=替代成员函数setValue。形式为operator=(int)的重载,把一个整数赋给currency类的对象,它替代了具有三个参数的成员函数setValue,x把符号、美元和美分都集中在一个整数里。形式为operator=(double x)的重载,代替的是仅有一个参数的成员函数setValue。
currency1_18.h

#ifndef currency_18_H
#define currency_18_H

#include<iostream>
#include"illegalParameterValue.h"
#include"signType.h"



class currency_18
{
    
    
	friend ostream& operator<<(ostream&, const currency_18&);
	friend istream& operator>>(istream&, currency_18&);
public:
	currency_18(int theAmount = 0);       //默认构造函数
	~currency_18(){
    
     }
	void operator=(int);
	void operator=(double);
	signType getSign() const {
    
    
		if (amount < 0) 
			return signType::minusc;
		else
			return signType::plusc;
	}

	unsigned long getDollars() const {
    
    
		if (amount < 0)
			return (-amount) / 100;
		else
			return amount / 100;
	}

	unsigned int getCents() const {
    
    
		if (amount < 0)
			return -amount - getDollars() * 100;
		else
			return amount - getDollars() * 100;
	}


	currency_18 operator-(const currency_18& x) const;
	currency_18 operator%(double) const;
	currency_18 operator*(double) const;
	currency_18 operator/(double) const;
	currency_18 operator+(const currency_18&)const;


	currency_18& operator+=(const currency_18& x) {
    
    
		amount += x.amount;
		return *this;
	}
	currency_18& operator-=(const currency_18& x) {
    
    
		amount -= x.amount;
		return *this;
	}
	

private:
	long amount;
};

#endif // !currency_18_H
#include "currency_18.h"



currency_18::currency_18(int x) {
    
    
	//有参构造函数
	operator=(x);
}

void currency_18::operator=(int x) {
    
    
	//x将符号、美元和美分都集中在一起 实际money = x/100;
	amount = x;
}

void currency_18::operator=(double theAmount) {
    
    
	if (theAmount < 0)
		amount = (long)((theAmount - 0.001) * 100);
	else
		amount = (long)((theAmount + 0.001) * 100);
	//取两个十位数
}

currency_18 currency_18::operator-(const currency_18& x) const
{
    
    
	currency_18 y;
	y.amount = amount - x.amount;
	return y;
}

currency_18 currency_18::operator%(double x) const
{
    
    
	currency_18 result;
	long a1 = amount;
	long a2 = (x + 0.001) * 100;
	long a = (long)a1 / a2;
	result.amount = amount - a * a2;
	return result;
}

currency_18 currency_18::operator*(double x) const
{
    
    
	currency_18 result;
	result.amount = x * this->amount;
	return result;
}

currency_18 currency_18::operator/(double x) const
{
    
    
	currency_18 result;
	long a1 = this->amount;
	double a3 = (double)a1 / x;
	result.amount = a3;
	return result;
}

currency_18 currency_18::operator+(const currency_18& x)const {
    
    
	//将x 和 this相加 
	currency_18 y;
	y.amount = amount + x.amount;
	return y;
}



ostream& operator<<(ostream& out,const currency_18& x) {
    
    
	long theAmount = x.amount;
	if (theAmount < 0) {
    
    
		cout << '-';
		theAmount = -theAmount;
	}

	long dollars = theAmount / 100;
	cout << '$' << dollars << '.';
	int cents = theAmount - dollars * 100;
	if (cents < 10)
		cout << '0';
	cout << cents;
	return out;
}

istream& operator>>(istream& input, currency_18& x)
{
    
    
	cout << "Please enter the type of sign dollars and cents:" << endl;
	double temp;
	input >> temp;
	x = temp;
	return input;
}

编写非递归程序计算n!。测试你的代码

int Factorial(int num) {
    
    
    int result = 1;
    while (num > 0) {
    
    
        result *= num;
        num--;
    }
    return result;
}

1)编写递归函数计算斐波那契数(Fibonacci) F n F_n Fn,测试你的代码
2)证明对于1)的代码,当计算 F n F_n Fn n > 2 n>2 n>2时, F i F_i Fi的计算多于一次。
3)编写非递归函数计算斐波那契数(Fibonacci) F n F_n Fn,对每一给斐波那契数,你的代码应该只计算一次。测试你的代码

2)证明不太会那种规范的写法,并且我感觉当n=3的时候 F 1 F_1 F1, F 2 F_2 F2都只计算了一次,不知道这步是怎么样的。
证明:
在这里插入图片描述
递归过程按此树展开,当 i ≠ n − 1 i\neq n-1 i=n1时, F i F_i Fi计算不止一次。使用DP算法可以极大改善多于分支的计算。

int rec_Fibonacci(int num) {
    
    
    if (num == 1 || num == 2) {
    
    
        return 1;
    }
    else {
    
    
        return rec_Fibonacci(num - 1) + rec_Fibonacci(num - 2);
    }
}

int norec_Fibonacci(int num) {
    
    
    int num1 = 1, num2 = 1;
    int temp = 0;
    if (num == 1 || num == 2) {
    
    
        return 1;
    }
    else {
    
    
        for (int i = 3; i <= num; i++) {
    
    
            temp = num1 + num2;
            num1 = num2;
            num2 = temp;
        }
        return temp;
    }

}

考察在下面的公式(1-4)中定义的函数 f f f,其中n是非负整数。
{ n / 2 n 是 偶 数 f ( 3 n + 1 ) n 是 奇 数 \left\{\begin{aligned}n/2\qquad n是偶数\\f(3n+1)\quad n是奇数\end{aligned}\right. { n/2nf(3n+1)n
2)确定函数的基础部分和递归部分。证明重复应用递归部分可以吧灯饰右侧的 f f f表达式准尉基础部分。
3)编写一个C++递归函数计算 f ( n ) f(n) f(n)。测试你的代码
4)使用2)的证明编写非递归函数计算f(n),不能使用循环。测试你的代码。

2)证明:
当 n = 偶 数 时 , f ( n ) = n / 2. 当 n = 奇 数 时 , f ( n ) = f ( 3 n + 1 ) . ∵ 3 n 是 奇 数 ( ∵ n 是 奇 数 ) ∴ 3 n + 1 是 偶 数 . ∴ f ( n ) = f ( 3 n + 1 ) = ( 3 n + 1 ) / 2 当n=偶数时,f(n)=n/2.\\ 当n = 奇数时,f(n)=f(3n+1).\\ \because 3n是奇数(\because n是奇数)\\ \therefore 3n+1是偶数.\\ \therefore f(n)=f(3n+1)=(3n+1)/2 n=f(n)=n/2.n=f(n)=f(3n+1).3nn3n+1.f(n)=f(3n+1)=(3n+1)/2

int rec_f(int n) {
    
    
    if (n % 2 == 0) {
    
    
        return n / 2;
    }
    else {
    
    
        return rec_f(3 * n + 1);
    }
}

int unrec_f(int n) {
    
    
    if (n % 2 == 0) {
    
    
        return n / 2;
    }
    else {
    
    
        return (3 * n + 1) / 2;
    }
}

附代码下载地址

猜你喜欢

转载自blog.csdn.net/qq_32577169/article/details/106982984