之前寫過自己的解法:http://www.shnenglu.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;
}