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=0n−1a[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 0≤i<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 0≤i<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=n−1时, 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/2n是偶数f(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).∵3n是奇数(∵n是奇数)∴3n+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;
}
}