使用“數制”解組合策略問題

問題:

序列123...N,N介于3和9之间,在其中加入+、-或者空格,使其和为0。

如123456,1-2 3-4 5+6 7,等价于1-23-45+67=0。


解答:

網上找來的代碼。

 

 1 //序列123...N,N介于3和9之间,在其中加入+、-或者空格,使其和为0,
 2 //如123456  1-2 3-4 5+6 7 等价于1-23-45+67=0。请问,如何获得所有组合?使用递归和非递归。
 3 //非递归算法
 4 #include <iostream>
 5 #include <cmath>
 6 using namespace std;
 7 
 8 void func (char* str);
 9 void calc (char* result);
10 
11 int main()
12 {
13     char str[] = "123456789";
14     func(str);
15     return 0;
16 }
17 
18 void func(char* str)
19 {
20     //初始化输出数组
21     int len = strlen(str);
22     char* result = new char[len*2];
23     for (int i = 0; i < len; i++)    {
24         result[i*2] = str[i];
25     }
26     result[len*2-1] = '\0';
27     
28     //模拟3进制的运算
29     char key[3] = {' ', '+', '-'};
30     int n = pow(3.0, len - 1);
31     for (int i = 0; i < n; i++)    {
32         //把i转换成3进制,计算每一位,转换成字符,填入字符串相应位置
33         int pos = len * 2 - 3; //个位数填入位置
34         int temp = i, mod;
35         do {
36             mod = temp % 3;
37             temp /= 3;
38             result[pos] = key[mod];
39             pos -= 2;
40         } while (temp > 0);
41         //高位补0
42         while (pos > 0)    {
43             result[pos] = key[0];
44             pos -= 2;
45         }
46         calc(result);  //计算结果并输出
47     }
48 
49     delete[] result;
50 }
51 
52 void calc(char* result)
53 {
54     int sum = 0, sign = 1, i = 0;
55     int temp = 0;
56     while (result[i] != '\0')    {
57         if (result[i] == ' ')    {
58             temp *= 10;
59         }
60         else if(result[i] == '+' || result[i] == '-')    {
61             sign = (result[i] == '+') ? 1 : -1;
62             sum += temp;
63             temp = 0;
64         }
65         else {
66             temp += sign * (result[i] - '0');
67         }
68         i++;
69     }
70     sum += temp;
71     if (sum == 0)    {
72         cout << result << endl;
73     }
74 }

 

 

説明:

序列123...N,在數字之間插入“+”、“-”或“ ”,N 個數字之間有 N-1 個間隔,所以一共有 3^(N-1) 种方法。

利用“數制”可以輕鬆產生這些組合排列。

二進制數表示法,就是用0\1兩個數的組合排列,一個 byte 有 8 個 bits, 就有 2^8 個組合排列數,因此可以表示 [0,255] 這些數。

十進制數就由十個符號 “0123456789” 組合排列得到。

現在反向思考,我們需要是所有的組合排列,用一個數字就可以表示一種組合排列。

所以可以用 [0,3^(N-1)] 這些數表示所有 N 位的三進制數。

就說這些,我只能說得這麽清楚了。


posted on 2013-09-29 23:24  mhgu  阅读(292)  评论(0编辑  收藏  举报