php中24点算法,关于24点算法(一)

#include

#include

#include

#include

#include

//基本操作符枚举

enum class Operator {

NONE,

ADD,

DEC,

MUL,

SUB

};

//重载输出基本操作符运算符

std::ostream & operator << (std::ostream & out, const enum class Operator op) {

switch (op) {

case Operator::ADD:

out << "+"; break;

case Operator::DEC:

out << "-"; break;

case Operator::MUL:

out << "*"; break;

case Operator::SUB:

out << "/"; break;

}

return out;

}

//结果节点

struct ResultNode {

ResultNode(int val) :result(val) {}

int result;

Operator calc_operator{ Operator::NONE };

const ResultNode * left{ nullptr };

const ResultNode * right{ nullptr };

ResultNode(const ResultNode &rh) {

result = rh.result;

calc_operator = rh.calc_operator;

left = rh.left;

right = rh.right;

}

ResultNode & operator = (const ResultNode& rh) {

result = rh.result;

calc_operator = rh.calc_operator;

left = rh.left;

right = rh.right;

return *this;

}

bool operator < (const ResultNode &rh) const

{

return result < rh.result;

}

bool isSingle() const{

return left == nullptr && right == nullptr;

}

};

//打印出一棵节点树

void PrintResult(std::ostream &out, const ResultNode & result){

if (result.left == nullptr) {

out << result.result;

return;

}

if (!result.left->isSingle())out << "(";

PrintResult(out, *result.left);

if (!result.left->isSingle())out << ")";

out << result.calc_operator;

if (!result.right->isSingle())out << "(";

PrintResult(out, *result.right);

if (!result.right->isSingle())out << ")";

}

//组合类实现,实现从一个结果集中取出N个的可能性 C(S,N)

template

class combination {

public:

explicit combination(const std::vector &val) : value(val) {

//std::sort(value.begin(), value.end());

auto size = value.size();//std::unique(value.begin(), value.end()) - value.begin();

bitsets.assign(size, 0);

if (size >= N) {

for (int i = 0; i < N; ++i) {

bitsets[i] = 1;

}

initflag = true;

}

}

void get_value(std::vector & in, std::vector & other){

for (auto i = 0; i < bitsets.size(); ++i) {

if (bitsets[i] == 1) {

in.push_back(value[i]);

}

else {

other.push_back(value[i]);

}

}

for (auto v = value.begin() + bitsets.size(); v != value.end(); ++v) {

other.push_back(*v);

}

}

//取出下一个可能的结果,如果没有结果了就返回false

bool next(std::vector & out, std::vector & other){

if (bitsets.size() < N) {

return false;

}

if (initflag) {

get_value(out, other);

initflag = false;

}

else {

auto f = std::prev_permutation(bitsets.begin(), bitsets.end());

if (f) get_value(out, other);

return f;

}

return true;

}

bool initflag;

std::vector bitsets;

std::vector value;

};

//最终结果集

std::set<:string> ResultSet;

//计算主要递归函数

int CalcEx(const std::vector &set, const int result){

if (set.size() == 1) {

if (result == set[0].result) {

std::stringstream ss;

PrintResult(ss, set[0]);

//std::cout << std::endl;

ResultSet.insert(ss.str());//这里可以有效避免重复

}

return 0;

}

combination source{ set };

std::vector next, other;

//不断的从结果集中取组合,然后组合成新的结果集,再次调用递归

while (source.next(next, other)) {

//ADD

{

auto _next = next;

auto _other = other;

ResultNode r(_next[0].result + _next[1].result);

r.left = &_next[0];

r.right = &_next[1];

r.calc_operator = Operator::ADD;

_other.push_back(r);

CalcEx(_other, result);

}

//DEC first-second

{

auto _next = next;

auto _other = other;

ResultNode r(_next[0].result - _next[1].result);

r.left = &_next[0];

r.right = &_next[1];

r.calc_operator = Operator::DEC;

_other.push_back(r);

CalcEx(_other, result);

}

//DEC second-first

{

auto _next = next;

auto _other = other;

ResultNode r(_next[1].result - _next[0].result);

r.left = &_next[1];

r.right = &_next[0];

r.calc_operator = Operator::DEC;

_other.push_back(r);

CalcEx(_other, result);

}

//MUL

{

auto _next = next;

auto _other = other;

ResultNode r(_next[0].result * _next[1].result);

r.left = &_next[0];

r.right = &_next[1];

r.calc_operator = Operator::MUL;

_other.push_back(r);

CalcEx(_other, result);

}

//SUB first/second

{

auto _next = next;

auto _other = other;

if (_next[1].result == 0 || (_next[0].result % _next[1].result) != 0)

goto NEXTSUB;

ResultNode r(_next[0].result / _next[1].result);

r.left = &_next[0];

r.right = &_next[1];

r.calc_operator = Operator::SUB;

_other.push_back(r);

CalcEx(_other, result);

}

NEXTSUB:

//SUB second/first

{

auto _next = next;

auto _other = other;

if (_next[0].result == 0 || (_next[1].result % _next[0].result) != 0)

goto CONTINUE;

ResultNode r(_next[1].result / _next[0].result);

r.left = &_next[1];

r.right = &_next[0];

r.calc_operator = Operator::SUB;

_other.push_back(r);

CalcEx(_other, result);

}

CONTINUE:

next.clear();

other.clear();

continue;

}

return 0;

}

TEST(Game24Test, TowValue) {

//计算2个值的情况

{

std::vector v;

v.push_back(12); v.push_back(12);

CalcEx(v, 24);

//输出 12+12

for (auto & result : ResultSet) {

std::cout << result << std::endl;

}

}

}

TEST(Game24Test, Unsolvable) {

ResultSet.clear();

//计算无解的情况

{

std::vector v;

v.push_back(3); v.push_back(2); v.push_back(3); v.push_back(4);

CalcEx(v, 24);

//无输出

for (auto & result : ResultSet) {

std::cout << result << std::endl;

}

}

}

int main(){

std::vector v;

v.push_back(3); v.push_back(3); v.push_back(6); v.push_back(6);

CalcEx(v, 24);

//无输出

for (auto & result : ResultSet) {

std::cout << result << std::endl;

}

return 0;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值