之前写过自己的解法:http://www.cppblog.com/izualzhy/archive/2011/11/29/161187.html
后来别人指点了下,于是修改了一番。
主要是几个方面:
1.界面先暂时去掉了,主要是算法本身增加了些判断。不过基本的想法没有改。
2.现在可以计算任意的输入了,不过我试了下,超过6个数就非常慢。。。不知道怎么修改。。。
3.写了一个新的类记录中间过程得到的数,重写了加减乘除等方法,这样就可以不像用之前ABS(a-b)<1e-5的方法判断两个数相等。
以四个数为例,记录下主要想法:
首先输入的数假定为 A B C D
排列共有24种情况,设一种为 a b c d
在肯定为该排列方式的情况下,有3种加括号的方式,同时设@为加减乘除的任意一种,于是有
(a@b) c d
a (b@c) d
a b (c@d)
共3x4=12种情况,于是之后得到三个数x y z,同样的加括号的方式有2种
(x@y) z
x (y@z)
得到两个数m n,一种加括号的方式:
m@n
于是得到一个数
M
检测这个M是否是目标数值。
最近开始学习数据结构与算法,想尽快补上之前计算机系学的基本课程来。感觉这个有点像回溯算法。
如果你又兴趣同时看完了代码的话,希望能告诉我一下哪里在复杂度需要改进的。
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
const int cardCounter = 4;
const double obj = 24;
//#define DEBUG
void calTwoCards(double a[], int lenA, double b[], int lenB, double src[lenA][lenB][4])
{
for ( int i=0; i<lenA; ++i)
for ( int j=0; j<lenB; ++j) {
calTwoCards(a[i], b[j], src[i][j]);
}
}
void calTwoCards(double a, double b, int lenB, double src[lenB][4])
{
for ( int i=0; i<lenB; ++i)
calTwoCards(a, b[i], src[i]);
}
void calTwoCards(double a, double b, double src[])
{
//a opeartor src[i] = b
src[0]=b+a;
src[1]=b-a;
src[2]=b*a;
src[3]=b/a;
}
char getOperator(int i)
{
if (i==0) return '+';
if (i==1) return '-';
if (i==2) return '*';
if (i==3) return '/';
}
void parseM(int m)
{
char c = getOperator(m%6);
char b = getOperator(m/6%6);
char a = getOperator(m/6/6%6);
cout << " " << a << " " << b << " " << c << endl;
}
void copy(double a[], double b[], int lenB)
{
for (int i=0; i<lenB; ++i)
a[i] = b[i];
}
void calCorrentExpression(double src[], double obj)
{
for ( int i=0; i<cardCounter; ++i) {
double srcFirst[cardCounter];
calTwoCards(src[i], obj, srcFirst);
for ( int j=0; j<cardCounter; ++j) {
if (j==i) continue;
double srcSecond[cardCounter][cardCounter];
calTwoCards(src[j], srcFirst, cardCounter, srcSecond);
for ( int p=0; p<cardCounter; ++p) {
if (p==j || p==i) continue;
double srcThird[cardCounter*cardCounter][cardCounter];
calTwoCards(src[p], srcSecond, cardCounter*cardCounter, srcThird);
for ( int q=0; q<cardCounter; ++q) {
if (q==i || q==j || q==p) continue;
for ( int m=0; m<cardCounter*cardCounter; ++m)
for ( int n=0; n<cardCounter; ++n)
if (src[q]-srcThird[m][n])
}
}
}
}
}
int main()
{
double baseDigit[4] = {5,5,5,1};
calCorrentExpression(baseDigit, 24);
return 0;
}