完成一个计算24点的代码
2007-05-20 02:54
417 查看
// Num.h
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef float (*PF)(float, float);
class Num
{
public:
Num();
~Num();
bool Compute() const;
static float Func1(float a, float b);
static float Func2(float a, float b);
static float Func3(float a, float b);
static float Func4(float a, float b);
private:
vector< float > *m_vf;
static const PF m_pf[4];
static const string op;
};
// Num.cpp
#include "Num.h"
float Num::Func1(float a, float b)
{
return a+b;
}
float Num::Func2(float a, float b)
{
return a-b;
}
float Num::Func3(float a, float b)
{
return a*b;
}
float Num::Func4(float a, float b)
{
return a/b;
}
const string Num::op = "+-*/";
const PF Num::m_pf[4] = {Num::Func1, Num::Func2, Num::Func3, Num::Func4};
Num::Num()
{
cout<<"Please input the num:"<<endl;
m_vf = new vector<float>;
if (m_vf == NULL)
{
cerr<<"There is no enough momery!"<<endl;
exit(1);
}
for (int i = 0; i < 4; i++)
{
float temp;
cin>>temp;
m_vf->push_back(temp);
}
}
Num::~Num()
{
delete m_vf;
}
bool Num::Compute() const
{
bool res = false;
//四个for列出四个数字的全排列
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
for (int k = 0; k < 4; k++)
for (int h=0; h < 4; h++)
{
if (i!=j && i!=k && i!=h && j!=k && j!=h && k!=h)
{
//三个for列出一个数字排列加入运算符后的计算组合
for (int l = 0; l < 4; l++)
for (int m = 0; m < 4; m++)
for (int n = 0; n < 4; n++)
{
//考虑运算符优先级以及括号
//a(b(cd))
float temp = m_pf[l]( (*m_vf)[i], m_pf[m]( (*m_vf)[j], m_pf
( (*m_vf)[k], (*m_vf)[h]) ) );
if (23.9 < temp && temp < 24.1)
{
cout<<(*m_vf)[i]<<op[l]<<'('
<<(*m_vf)[j]<<op[m]<<'('
<<(*m_vf)[k]<<op
<<(*m_vf)[h]<<")) = 24"<<endl;
res = true;
}
//(ab)(cd)
temp = m_pf[m]( m_pf[l]( (*m_vf)[i], (*m_vf)[j] ), m_pf
( (*m_vf)[k], (*m_vf)[h] ) );
if (23.9 < temp && temp < 24.1)
{
cout<<'('<<(*m_vf)[i]<<op[l]
<<(*m_vf)[j]<<')'<<op[m]<<'('
<<(*m_vf)[k]<<op
<<(*m_vf)[h]<<") = 24"<<endl;
res = true;
}
//a((bc)d)
temp = m_pf[l]( (*m_vf)[i], m_pf
( m_pf[m]( (*m_vf)[j], (*m_vf)[k] ), (*m_vf)[h] ) );
if (23.9 < temp && temp < 24.1)
{
cout<<(*m_vf)[i]<<op[l]<<"(("
<<(*m_vf)[j]<<op[m]
<<(*m_vf)[k]<<')'<<op
<<(*m_vf)[h]<<") = 24"<<endl;
res = true;
}
//(a(bc))d
temp = m_pf
( m_pf[l]( (*m_vf)[i] , m_pf[m]( (*m_vf)[j], (*m_vf)[k] ) ), (*m_vf)[h] );
if (23.9 < temp && temp < 24.1)
{
cout<<'('<<(*m_vf)[i]<<op[l]<<'('
<<(*m_vf)[j]<<op[m]
<<(*m_vf)[k]<<"))"<<op
<<(*m_vf)[h]<<" = 24"<<endl;
res = true;
}
//((ab)c)d
temp = m_pf
( m_pf[m]( m_pf[l]( (*m_vf)[i], (*m_vf)[j] ), (*m_vf)[k] ), (*m_vf)[h] );
if (23.9 < temp && temp < 24.1)
{
cout<<"(("<<(*m_vf)[i]<<op[l]
<<(*m_vf)[j]<<')'<<op[m]
<<(*m_vf)[k]<<')'<<op
<<(*m_vf)[h]<<" = 24"<<endl;
res = true;
}
}
}
}
return res;
}
//main.cpp
#include "Num.h"
int main()
{
Num eg;
if ( !eg.Compute() )
{
cout<<"The 4 numbers can not return 24!"<<endl;
}
return 0;
}
几点说明:
1、Func1~Func4可以合并成一个函数Func(float a, float b, int c)用c来判断是进行哪种运算,这样就不用定义一个函数指针数组,这样就可以把Func放到private区有利于更好的封装,不过可能要影响程序的可读性;
2、对于四个输入数字的全排列,可以考虑使用范型算法next_permutation(),它将[first,last)之间的元素重新排序为下一个排列,如果不存在下一个排列则返回false;由于算法的排序特征(从升序排到降序为止),所以进入循环前必须先对元素进行排序,且至少要保证一次循环,所以采用do-while循环。采用范型算法实现还有一个优点就是对于有相等数字的排列(1667),其只计算了一组。而上面的算法则计算了两组(两个6交换了位置)。
3、语法层次上要注意类静态成员的声明与定义方法(ODR法则);
4、注意vector的用法,思考下为什么类成员变量要定义为vector的指针,如果我们用数组来实现,那么这个类的构造函数又应该如何改写呢?
#include <iostream>
#include <vector>
#include <string>
using namespace std;
typedef float (*PF)(float, float);
class Num
{
public:
Num();
~Num();
bool Compute() const;
static float Func1(float a, float b);
static float Func2(float a, float b);
static float Func3(float a, float b);
static float Func4(float a, float b);
private:
vector< float > *m_vf;
static const PF m_pf[4];
static const string op;
};
// Num.cpp
#include "Num.h"
float Num::Func1(float a, float b)
{
return a+b;
}
float Num::Func2(float a, float b)
{
return a-b;
}
float Num::Func3(float a, float b)
{
return a*b;
}
float Num::Func4(float a, float b)
{
return a/b;
}
const string Num::op = "+-*/";
const PF Num::m_pf[4] = {Num::Func1, Num::Func2, Num::Func3, Num::Func4};
Num::Num()
{
cout<<"Please input the num:"<<endl;
m_vf = new vector<float>;
if (m_vf == NULL)
{
cerr<<"There is no enough momery!"<<endl;
exit(1);
}
for (int i = 0; i < 4; i++)
{
float temp;
cin>>temp;
m_vf->push_back(temp);
}
}
Num::~Num()
{
delete m_vf;
}
bool Num::Compute() const
{
bool res = false;
//四个for列出四个数字的全排列
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
for (int k = 0; k < 4; k++)
for (int h=0; h < 4; h++)
{
if (i!=j && i!=k && i!=h && j!=k && j!=h && k!=h)
{
//三个for列出一个数字排列加入运算符后的计算组合
for (int l = 0; l < 4; l++)
for (int m = 0; m < 4; m++)
for (int n = 0; n < 4; n++)
{
//考虑运算符优先级以及括号
//a(b(cd))
float temp = m_pf[l]( (*m_vf)[i], m_pf[m]( (*m_vf)[j], m_pf
( (*m_vf)[k], (*m_vf)[h]) ) );
if (23.9 < temp && temp < 24.1)
{
cout<<(*m_vf)[i]<<op[l]<<'('
<<(*m_vf)[j]<<op[m]<<'('
<<(*m_vf)[k]<<op
<<(*m_vf)[h]<<")) = 24"<<endl;
res = true;
}
//(ab)(cd)
temp = m_pf[m]( m_pf[l]( (*m_vf)[i], (*m_vf)[j] ), m_pf
( (*m_vf)[k], (*m_vf)[h] ) );
if (23.9 < temp && temp < 24.1)
{
cout<<'('<<(*m_vf)[i]<<op[l]
<<(*m_vf)[j]<<')'<<op[m]<<'('
<<(*m_vf)[k]<<op
<<(*m_vf)[h]<<") = 24"<<endl;
res = true;
}
//a((bc)d)
temp = m_pf[l]( (*m_vf)[i], m_pf
( m_pf[m]( (*m_vf)[j], (*m_vf)[k] ), (*m_vf)[h] ) );
if (23.9 < temp && temp < 24.1)
{
cout<<(*m_vf)[i]<<op[l]<<"(("
<<(*m_vf)[j]<<op[m]
<<(*m_vf)[k]<<')'<<op
<<(*m_vf)[h]<<") = 24"<<endl;
res = true;
}
//(a(bc))d
temp = m_pf
( m_pf[l]( (*m_vf)[i] , m_pf[m]( (*m_vf)[j], (*m_vf)[k] ) ), (*m_vf)[h] );
if (23.9 < temp && temp < 24.1)
{
cout<<'('<<(*m_vf)[i]<<op[l]<<'('
<<(*m_vf)[j]<<op[m]
<<(*m_vf)[k]<<"))"<<op
<<(*m_vf)[h]<<" = 24"<<endl;
res = true;
}
//((ab)c)d
temp = m_pf
( m_pf[m]( m_pf[l]( (*m_vf)[i], (*m_vf)[j] ), (*m_vf)[k] ), (*m_vf)[h] );
if (23.9 < temp && temp < 24.1)
{
cout<<"(("<<(*m_vf)[i]<<op[l]
<<(*m_vf)[j]<<')'<<op[m]
<<(*m_vf)[k]<<')'<<op
<<(*m_vf)[h]<<" = 24"<<endl;
res = true;
}
}
}
}
return res;
}
//main.cpp
#include "Num.h"
int main()
{
Num eg;
if ( !eg.Compute() )
{
cout<<"The 4 numbers can not return 24!"<<endl;
}
return 0;
}
几点说明:
1、Func1~Func4可以合并成一个函数Func(float a, float b, int c)用c来判断是进行哪种运算,这样就不用定义一个函数指针数组,这样就可以把Func放到private区有利于更好的封装,不过可能要影响程序的可读性;
2、对于四个输入数字的全排列,可以考虑使用范型算法next_permutation(),它将[first,last)之间的元素重新排序为下一个排列,如果不存在下一个排列则返回false;由于算法的排序特征(从升序排到降序为止),所以进入循环前必须先对元素进行排序,且至少要保证一次循环,所以采用do-while循环。采用范型算法实现还有一个优点就是对于有相等数字的排列(1667),其只计算了一组。而上面的算法则计算了两组(两个6交换了位置)。
3、语法层次上要注意类静态成员的声明与定义方法(ODR法则);
4、注意vector的用法,思考下为什么类成员变量要定义为vector的指针,如果我们用数组来实现,那么这个类的构造函数又应该如何改写呢?
相关文章推荐
- 一个简单方法完成C#时间间隔的计算
- Linux内核分析:完成一个简单的时间片轮转多道程序内核代码
- Linux内核分析,完成一个简单的时间片轮转多道程序内核代码
- 一个python远程机群计算的垃圾代码
- 最近距离 已知平面上的若干点的位置,存入一个List中。现在需要计算所有这些点中, 距离最近的两个点间的最小距离。请补全缺失的代码。
- 一个简单方法完成C#时间间隔的计算
- Linux 内核分析 第二次作业 完成一个简单的时间片轮转多道程序内核代码
- 计算一个项目有多少行代码
- 一个简单的代码计算行数demo编写
- 实验二:完成一个简单的时间片轮转多道程序内核代码
- 例题:计算运费。c#语言基础,比较简单。看代码输入格式和方法。同样方法可以做一个 出租车打车的程序
- 一个简单方法完成C#时间间隔的计算
- 11行代码完成一个超级简单爬虫
- 一个简单方法完成C#时间间隔的计算
- 嵌入式系统经常具有要求程序员去访问某特定的内存位置的特点。在某工程中,要求设置一绝对地址为0x67a9的整型变量的值为0xaa66。编译器是一个纯粹的ANSI编译器。写代码去完成这一任务。
- 最少javascript代码完成一个2048游戏
- 编写C 代码,计算一个字节中被置 1 的位的个数(4种解法)
- linux内核分析作业:操作系统是如何工作的进行:完成一个简单的时间片轮转多道程序内核代码
- 一个计算周次和本周时间范围的代码(c#)[转]
- 【java学习记录】2.定义一个计算矩形面积、立方体和球体体积的类,该类完成计算的方法用静态方法实现