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 배열 a[start:end-1]에 값을 할당하는 템플릿 함수 채우기를 작성합니다. 코드를 테스트합니다.
//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[ 나는 ]}∑나는 = 0n - 1ㅏ [ 나는 ]∗b [ 나는 ] . 코드를 테스트합니다.
//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 a[i]=value+i, 0 ≤ i < n 0\leq i<n이 되도록 템플릿 함수 iota를 작성합니다.0≤나<엔 . 코드를 테스트합니다.
//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 템플릿 함수를 작성하세요. 코드를 테스트합니다.
//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 템플릿 함수 불일치 작성, 반환 값은 부등식 a [ i ] ≠ b [ i ] a[i]\neq b[i]ㅏ [ 나는 ].=b [ i ] 가 성립하는는 0 ≤ i < n 0\leq i<n0≤나<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보다 작으면 throw된 예외 값은 1이고, a, b, c가 모두 0이면 throw된 예외 값은 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입니다. [나]
/*
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 1차원 배열의 길이를 oldLength에서 newLength로 변경하는 템플릿 함수 changeLength1D를 작성합니다. 이 함수는 먼저 길이가 newlength인 새 배열을 할당한 다음 원래 배열의 첫 번째 min{oldLength, newLength} 요소를 새 배열에 복사하고 마지막으로 원래 배열이 차지하는 공간을 해제합니다. 코드를 테스트합니다.
여기서는 기본 메모리의 분배가 필요하고 new를 사용하여 생성된 배열이 힙 메모리에 분배되기 때문에 여기서는 비교적 바보 같은 방법을 사용하고 있습니다. 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 2차원 배열의 크기를 변경하는 함수 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의 통화 클래스를 확장하고 다음 멤버 함수를 추가합니다.
1) input()은 표준 입력 스트림에서 통화 값을 읽은 다음 호출 개체에 할당합니다.
2) 빼기(x) 호출 개체에서 매개 변수 개체 x의 값을 뺀 다음 호출 개체에 할당합니다.
3) 퍼센트(x)는 값이 호출 객체의 x%인 통화 클래스 객체를 반환합니다. x의 데이터 유형은 double입니다.
4) 곱하기(x)는 값이 호출 개체와 이중 숫자 x의 곱인 통화 클래스 개체를 반환합니다.
5) Divide(x)는 통화 클래스의 객체를 반환하고 그 값은 호출 객체를 이중 숫자 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)의 오버로드는 통화 클래스의 개체에 정수를 할당하고 멤버 함수 setValue를 3개의 매개 변수로 대체하며 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을 계산하는 재귀 함수를 작성하십시오.에프엔, 코드를 테스트하려면 2) F n F_n을
계산할 때 1)의 코드에 대해 증명하십시오.에프엔그리고 n > 2 n>2N>2时,F i F_i에프나한 번 이상 계산됩니다.
3) 비재귀 함수를 작성하여 피보나치 수(Fibonacci) F n F_n을 계산합니다.에프엔, 코드는 주어진 각 피보나치 수에 대해 한 번만 계산해야 합니다. 코드 테스트
2) 그런 표준적인 글쓰기에 그다지 능숙하지 않다는 것을 증명하고, n=3 일 때 F 1 F_1에프1, 에프 2 에프_2에프2한 번밖에 계산을 해보지 않아서 이 단계가 어떤지 모르겠습니다.
증명:
재귀 과정은 i ≠ n − 1 i\neq n-1 일 때 이 트리에 따라 확장됩니다.나.=N-1时,F i F_i에프나두 번 이상 계산되었습니다. 분기보다 많은 계산은 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)에 정의된 함수 ff를 고려하십시오.f , 여기서 n은 음이 아닌 정수입니다.
{ n / 2 n은 짝수 f ( 3 n + 1 ) n은 홀수\left\{\begin{aligned}n/2\qquad n은 짝수\\f(3n+1)\quad n은 홀수\end{align}\right입니다.{
n / 2n 은 짝수에프 ( 3 엔+1 )n 은 홀수 입니다.
2) 함수의 기본 부분과 재귀 부분을 결정합니다. 재귀 부분의 반복적용이 옳다는 증명F 표현 영장관의 기본적인 부분. 3) f(n) f(n)을
계산하는 C++ 재귀 함수를 작성합니다.에프 ( 엔 ) . 코드 테스트
4) 2)의 증명을 사용하여 루프를 사용하지 않고 f(n)을 계산하는 비재귀 함수를 작성합니다. 코드를 테스트합니다.
2) 증명:
n = 짝수일 때 f(n ) = n / 2 n = 홀수일 때 f(n ) = f( 3n + 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).\\ \왜냐하면 3n은 홀수이기 때문입니다(\왜냐하면 n은 홀수이기 때문입니다.\\ \그러므로 3n+1은 짝수입니다.\\ \그러므로 f(n) =f(3n +1)=(3n+1)/2언제 n=짝수 의 경우 , f ( n )=n / 2 .언제 n=홀수 일 때 , f ( n )=에프 ( 3 엔+1 ) .∵3n 은 홀수 ( _∵n 은 홀수 )∴3 엔+1 은 짝수 입니다 .∴에프 ( 엔 )=에프 ( 3 엔+1 )=( 3 엔+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;
}
}