C++ 语言程序设计基础 - 学堂在线
这篇主要是这个课程的所有课后习题的答案与代码,附加个人的见解
持续更新直到学完进阶版,所以周期可能很长
第1章 绪论
第3章 函数
函数定义
单选题
void test()
{
return;
}
函数test定义如上,是否正确()是
question(int a)
{
return a;
}
函数question定义如上,它缺失了()返回值类型
函数调用
例3-9 中的代码如下:
#include "stdafx.h"
#include <iostream>
using namespace std;
int comm(int n, int k)
{
if (k > n)
return 0;
else if (n == k || k == 0)
return 1;
else
return comm(n - 1, k) + comm(n - 1, k - 1);
}
int main()
{
int n, k;
cin >> n >> k;//输入n,k
cout << comm(n, k) << endl;//输出答案
return 0;
}
函数comm在输入为 n=5,k=9 时的返回值为:___ 0
C3-1 直角三角形
题目描述
输入一个三角形的3边长度,判断该三角形是否为直角三角形,若是则输出True,若不是则输出False。推荐做法:定义一个函数,接受三个int参数,返回bool,再用主函数调用之。
#include <cmath>
#include <iostream>
using namespace std;
bool isTriangle(int a, int b, int c)
{
if ( pow(a,2)+pow(b,2)==pow(c,2) || pow(c, 2) + pow(b, 2) == pow(a, 2) || pow(a, 2) + pow(c, 2) == pow(b, 2))
return true;
else
return false;
}
int main()
{
int a, b, c;
while (cin >> a >> b >> c)
{
if (isTriangle(a, b, c))
cout << "True" << endl;
else
cout << "False" << endl;
}
return 0;
}
一开始纠结到底输入几行才结束,看到其他人的写法,才知道我的cline是多余了… /笑哭
while (cin>>a>>b>>c)
C3-2 斐波那契数列
题目描述
斐波那契数列f(n)满足以下定义:f(0) = 1, f(1) = 1, f(n) = f(n-1) + f(n-2) (n >= 2)。请用递归的方法编写函数,对于给定的n,求出斐波那契数列的第n项f(n)
#include <cmath>
#include <iostream>
using namespace std;
int fibo(int a)
{
if (a==0 || a==1)
{
return 1;
}
else
{
return fibo(a - 1) + fibo(a - 2);
}
}
int main()
{
int n;
while (cin >> n)
{
cout << fibo(n);
}
}
一开始做完上题忘记改bool了,一直输出1… 我真是…
C3-3 丑数
题目描述
只包含因子2,3,5的正整数被称作丑数,比如4,10,12都是丑数,而7,23,111则不是丑数,另外1也不是丑数。请编写一个函数,输入一个整数n,能够判断该整数是否为丑数,如果是,则输出True,否则输出False。
#include <iostream>
using namespace std;
bool Judge(int a)
{
if (a==1)
{
return false;
}
int div[3] = { 2,3,5 };
int flag;
for (int i :div)
{
while (a%i == 0)
{
a = a / i;
}
}
return (a==1);
}
int main()
{
int n;
while (cin >> n)
{
if (Judge(n))
cout << "True" << endl;
else
cout << "False" << endl;
}
}
注意读题:只包含 2,3,5,111之所以不是是因为3*37,37是质数…(没错,我就是那个直接if % % % 了一下,一下没看到错误…
第4章 类与对象
C4-1 最大公约数
题目描述
求两个正整数a 和 b的最大公约数。要求使用c++ class编写程序。可以创建如下class
#include <iostream>
using namespace std;
class Integer {
private:
int _num;
public:
//构造函数
Integer(int num)
{
_num = num;
}
//计算当前Integer 和 b之间的最大公约数
int gcd(Integer b)
{
int min = _num < b._num ? _num : b._num;
int max = _num > b._num ? _num : b._num;
for (int i = min; i >= 1; i--)
{
if (max%i == 0 && min%i == 0)
{
return i;
}
}
}
};
int main() {
int a, b;
cin >> a >> b;
Integer A(a);
Integer B(b);
cout << A.gcd(B) << endl;
return 0;
}
这个题一直没搞懂应该咋比较两个数,后面才知道输入进来的也是一个类,那里面的_num和A中的进行对比。
C4-2 反转整数
题目描述
对于输入的一个正整数,输出其反转形式
#include <cmath>
#include <iostream>
using namespace std;
class Integer {
private:
int _num;
//getLength()函数获取_num长度
int getLength()
{
int i = 0;
int temp = _num;
while (temp!=0)
{
temp = temp / 10;
i++;
}
return i;
}
public:
//Integer类构造函数
Integer(int num)
{
_num = num;
}
//反转_num
int inversed()
{
int result = 0 ;
for (int j = getLength(); j >0 ; j--)
{
result += _num % 10 * pow(10, j-1);
_num = _num / 10;
}
return result;
}
};int main() {
int n;
cin >> n;
Integer integer(n);
cout << integer.inversed() << endl;
return 0;
}
这个没啥问题,写出来的
C4-3 一元二次方程求解
题目描述
对于一元二次方程ax^2 + bx + c = 0,解可以分为很多情况。若该方程有两个不相等实根,首先输出1,换行,然后从小到大输出两个实根,换行;若该方程有两个相等实根,首先输出2,换行,然后输出这个这个实根,换行;若该方程有一对共轭复根,输出3,换行;若该方程有无解,输出4,换行;若该方程有无穷个解,输出5,换行;若该方程只有一个根,首先输出6,换行,然后输出这个跟,换行;
#include <iomanip>
#include <iostream>
#include <cmath>
using namespace std;
class Equation {
private:
int _a, _b, _c;
public:
Equation(int a, int b, int c)
{
_a = a; _b = b; _c = c;
}
double result[2];
void solve()
{
float deta = pow(_b, 2) - 4.0 * _a*_c;
if (_a == 0)
{
if ( _b != 0)
{
cout << 6 << endl;
cout << setiosflags(ios::fixed) << setprecision(2) << (float) -_c / _b << endl;
}
else if ( _b == 0 && _c == 0)
{
cout << 5 << endl;
}
else if ( _b == 0 && _c != 0)
{
cout << 4 << endl;
}
}
else
{
if (deta<0)
{
cout << 3 << endl;
}
else if (deta == 0)
{
cout << 2 << endl;
cout << setiosflags(ios::fixed) << setprecision(2) << -_b / (2.0*_a) << endl;
}
else if (deta>0)
{
result[0] = (-_b + sqrt(deta)) / (2.0 * _a);
result[1] = (-_b - sqrt(deta)) / (2.0 * _a);
cout << 1 << endl;
if (result[0]>result[1])
{
cout << setiosflags(ios::fixed) << setprecision(2) << result[1] << ' ' << result[0] << endl;
}
else
{
cout << setiosflags(ios::fixed) << setprecision(2) << result[0] << ' ' << result[1] << endl;
}
}
}
}
};
int main() {
int a, b, c;
cin >> a >> b >> c;
Equation tmp(a, b, c);
tmp.solve();
return 0;
}
这个题两个坑点:1. 保留2位有效数字,2. 整数计算记得转成浮点数, 3. 小的先输出也得要if因为a可能是负数,/笑哭
第5章 数据共享与保护
C5-1 “鱼额宝”
题目描述
请实现一个“鱼额宝”类,下面已给出代码模板,请根据main函数中对该类的操作,补充类实现部分完成代码。“鱼额宝”类可以记录账户余额、存钱、取钱、计算利息。该类中有一个私有静态成员变量profitRate存储“鱼额宝”的利率,可以用共有静态成员函数setProfitRate修改利率的值。程序输入为第1天至第n天连续n天的账户操作,每天只能进行一次账户操作,或存或取,每一天产生的利息是前一天的账户余额与“鱼额宝”利率的乘积,产生的利息当天也将存入账户余额,由于第1天之前账户不存在,所以第1天一定是新建账户并存钱,且当天不会有利息存入余额。程序在接受n天操作的输入后,要求计算出第n天操作完成后的账户余额并输出。
#include <iostream>
using namespace std;
class Yuebao
{
private:
static double profitRate;
double balance;
public:
Yuebao(double balance):balance(balance) //构造函数
{ }
static void setProfitRate(double rate)
{
profitRate = rate;
}
void addProfit()
{
balance += balance*profitRate;
}
void deposit(double amount)
{
balance += amount;
}
void withdraw(double amount)
{
balance -= amount;
}
double getBalance()
{
return balance;
}
};
double Yuebao::profitRate = 0;
int main()
{
int n;
while (cin >> n)
{
double profitRate;
cin >> profitRate;
Yuebao::setProfitRate(profitRate);//设定鱼额宝的利率
Yuebao y(0); //新建鱼额宝账户,余额初始化为0
int operation;//接受输入判断是存还是取
double amount;//接受输入存取金额
for (int i = 0; i < n; ++i)
{
y.addProfit();//加入前一天余额产生的利息
cin >> operation >> amount;
if (operation == 0)
y.deposit(amount);//存入金额
else
y.withdraw(amount);//取出金额
}
cout << y.getBalance() << endl;//输出最终账户余额
}
return 0;
}
一开始一直不太懂那个构造函数的出现… 后来才发现新建账户的时候需要输入,得申明的感觉
C5-2 数老鼠
题目描述
请实现一个老鼠类,下面已给出代码模板,请根据main函数中对该类的操作,补充类实现部分完成代码。该类有个公有静态变量num记录该类的所有对象数,主函数将会在不同语句之后输出对象数,只有正确地实现该类,保证num正确记录该类的对象数,才能输出正确的结果。
#include <iostream>
using namespace std;class Mouse
{
public:
static int num;
Mouse() { num++; }//构造函数
Mouse(const Mouse &m) { num++; }//复制构造函数
~Mouse() { num--; }
};
int Mouse::num = 0;
void fn(Mouse m);int main()
{
Mouse::num = 0;
Mouse a;
cout << Mouse::num << endl;
Mouse b(a);
cout << Mouse::num << endl;
for (int i = 0; i < 10; ++i)
{
Mouse x;
cout << Mouse::num << endl;
}
fn(a);
cout << Mouse::num << endl;
return 0;
}void fn(Mouse m)
{
cout << Mouse::num << endl;
Mouse n(m);
cout << Mouse::num << endl;
}
这里当时没写出复制构造函数… 虽然我现在都没怎么理解完全,写的也是参考的百度上的几位的才看出自己的错误。
第6章 数组、指针与字符串
C6-1 最大子数组和
题目描述
给定一个数组a[0,…,n-1],求其最大子数组(长度>=1)和
输入描述第一行一个整数n(1<=n<=5000),然后依次输入n个整数(每个整数范围[-5000, 5000])
输出描述输出一个整数表示最大子数组和
原谅我… 一开始连题目都没看懂,后面看了一幅图,恍然大悟… 贴图:百度来源
/*students please write your program here*/
#include <vector>
#include <iostream>
using namespace std;
int GetMax(int a, int b) //得到两个数的最大值
{
return (a) > (b) ? (a) : (b);
}int GetMaxAddOfArray(const vector<int> &arr, int sz)
{
int Sum = arr[0]; //临时最大值
int MAX = arr[0]; //比较之后的最大值
for (int i = 1; i < sz; i++)
{
Sum = GetMax(Sum + arr[i], arr[i]); //状态方程
if (Sum >= MAX)
MAX = Sum;
}
return MAX;
}
int main()
{
unsigned n;
cin >> n;
vector<int> array(n);
for (unsigned i = 0; i < n; i++)
{
cin >> array[i];
}
int MAX = GetMaxAddOfArray(array, n);
cout << MAX << endl;
return 0;
}
C6-2 字符串的回文子序列个数
题目描述
求一个长度不超过15的字符串的回文子序列个数(子序列长度>=1)。
关于回文子序列的一些知识:CSDN另一篇介绍
#include <string>
#include <iostream>
using namespace std;
string str_input, creat = "";
bool used[20] = { false };
int ans = 0;bool Judge(string str)
{
for (int i = 0; i < str.length()/2; i++)
{
if (str[i] != str[str.length() - i - 1])
return false;
}
return true;
}
void search(int len, int start)
{
if (len<=0)
{
if (Judge(creat))
{
ans++;
cout << creat << endl;
}
return;
}
for (int i = start; i < str_input.length(); i++)
{
if (!used[i])
{
used[i] = true;
creat.append(str_input, i, 1);
search(len - 1, i + 1);
used[i] = false;
creat.erase(creat.length() - 1, 1);
}
}
}
int main()
{
cin >> str_input;
for (int i = 1; i < str_input.length(); i++)
{
search(i, 0);
}
cout << ans; return 0;
}
基础课程算是全部听完了,到后面的编程题还是有点难的6-2完全是写的百度的一个写法,但是有些没有理解,自己写了一个… 然而错误百出,只能手算了一系列过程大概能知道,但是… 写不出来