c++语言风格
将一元硬币兑换成1 、2、 5分硬币,有多少种兑换方法?
动态规划
#include <iostream>
using namespace std;
//函数接受一个整数参数 `amount`,代表要兑换的金额。
int countCoinChange(int amount) {
int coins[] = {1, 2, 5};//coins 数组保存了可用的硬币面额。
int n = sizeof(coins) / sizeof(coins[0]);
int dp[amount + 1];//dp 数组用于保存兑换方法数量的动态规划表。
memset(dp, 0, sizeof(dp));//初始化 dp 数组
dp[0] = 1;
//两个嵌套循环来计算 dp 数组的其他元素
for (int i = 0; i < n; i++) {
for (int j = coins[i]; j <= amount; j++) {
dp[j] += dp[j - coins[i]];//dp[j] 的值增加 dp[j - coins[i]],表示使用当前硬币面额的兑换方法
}
}
return dp[amount];//返回 dp[amount],即兑换目标金额的兑换方法数量
}
int main() {
int amount;
cout << "输入金额(以分为单位): ";
cin >> amount;
int numWays = countCoinChange(amount);
cout << "数量: " << numWays << endl;
return 0;
}
#include <iostream>
#include <vector>
int coinChange(int amount) {
std::vector<int> dp(amount + 1, 0);
dp[0] = 1; // 初始条件
int coins[] = {1, 2, 5};
int numCoins = sizeof(coins) / sizeof(coins[0]);
for (int i = 0; i < numCoins; i++) {
for (int j = coins[i]; j <= amount; j++) {
dp[j] += dp[j - coins[i]];
}
}
return dp[amount];
}
int main() {
int amount = 100; // 兑换金额
int numWays = coinChange(amount);
std::cout << "Number of ways: " << numWays << std::endl;
return 0;
}
#include <iostream>
using namespace std;
int main() {
int ways = 0;
for (int a = 0; a <= 100; a++) {
for (int b = 0; b <= 50; b++) {
for (int c = 0; c <= 20; c++) {
if (a + b * 2 + c * 5 == 100)
ways++;
}
}
}
cout << "兑换方法数:" << ways << endl;
return 0;
}
由于我们通过虚函数实现了父类对象指针来访问子类对象的成员函数,但是假如现在我们要在主函数中修改Manager
对象的固定工资fixSalary
,这时我们会发现有两个问题:
emp
父类对象指针并没有访问Manager私有对象fixSalary
的权限.emp
的对象是指向Manager
对象的。解决方案:
#include <iostream>
#include <vector>
#include <ctime>
#include <algorithm>
#include <typeinfo>
#include "employee.h"
#include "technician.h"
#include "saleMan.h"
#include "saleManager.h"
#include "manager.h"
using namespace std;
int main()
{
Employee *emp[] = { new Manager(),new Technician(), new SaleMan(), new SaleManager()};
//cout << sizeof(emp) << endl;
//cout << sizeof(emp[0]) << endl;
for (int i = 0; i < sizeof(emp) / sizeof(emp[i]); i++)
{
emp[i]->init();
if (typeid(*emp[i]).name() == typeid(Manager).name()) //运行时类型信息
{
//这一步至关重要,要判断当前类型是否与正在转换成的类型是否有一种 “is a”的关系。
//如果当前类型与正在转换的类型不是一种“is a” 关系的话,从内存布局的角度看,这时的指针指向是十分危险的。
cout << typeid(*emp[i]).name() << endl;
cout << typeid(Manager).name() << endl;
dynamic_cast<Manager*>(emp[i])->addSalary(1000);
// 首先在Manager原有基础上增加addSalary()函数才能访问到fixSalary私有变量
//然后利用dynamic_cast 一种运行时的类型转化方式,
//将父类对象指针强制转换为子类对象指针再调用addSalary()函数。
}
emp[i]->getPay();
cout << "-----------------" << endl;
emp[i]->displayInfo();
cout << "-----------------" << endl;
}
return 1;
}
测试结果:
多态下使用 typeid 时要注意的问题:
确保基类定义了至少一个虚函数(虚析构也算)。
不要将 typeid 作用于指针,应该作用于引用,或解引用的指针。
typeid 是一个运算符,而不是函数。
typeid 运算符返回的 type_info 类型,其拷贝构造函数和赋值运算函数都声明为private 了,这意味着其不能用于 stl 容器,所以我们一般不能不直接保存 type_info 信息,而保存 type_info 的 name 信息
关于dynamic_cast之外的其他强制转换
static_cast:在一个方向上可以作隐式转换的,在另外一个方向上可以作静态转换。发生在编译阶段,不保证后序使用的正确性。
reinterpreter_cast:既不在编译器期也不在运行期进行检查,安全性完全由程序员决定。
dynamic_cast:dynamic_cast 一种运行时的类型转化方式,所以要在运行时作转换判断。检查指针所指类型,然后判断这一类型是否与正在转换成的类型有一种 “is a”的关系,如果是,dynamic_cast 返回对象地址。如果不是,dynamic_cast 返回 NULL。dynamic_cast 常用多态继承中,判断父类指针的真实指向。
##################################################################################################
示例代码工程:
上面示例代码完整的VS工程打包放在下面这个链接:简易的员工信息管理系统
我可以帮助你编写一个C++风格的程序来解决百钱问题。以下是解决该问题的步骤:
下面是一个示例代码:
#include <iostream>
using namespace std;
int coinChange(int n) {
int dp[n+1] = {0};
dp[0] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= 5; j++) {
if (j <= i) {
dp[i] += dp[i - j];
}
}
}
return dp[n];
}
int main() {
int amount;
cout << "请输入要兑换的金额:";
cin >> amount;
int count = coinChange(amount);
cout << "兑换方法的数量为:" << count << endl;
return 0;
}
通过运行这个程序,你可以输入要兑换的金额,并得到兑换方法的数量。
请注意,这只是一个示例代码,你可以根据实际情况作出适当的修改。