您的位置:首页 > 其它

计算几个数相加和为16

2017-12-28 11:05 169 查看
##

/************************************************************************/
/*        功能:计算几个数和是否等于16
/*        日期:2017年12月
/*        作者:骆国辉
/************************************************************************/

#include <stdio.h>
#include <stack>
#include <vector>
#include <time.h>

class SumCombine {
public:
SumCombine(int* data, int length, int target_value) : numbers(data), num_length(length), target(target_value) {
result_num = 0;
}

enum Result { EQUAL = 0, LARGER = 1, SMALLER = 2, INVALID_INDEX = 3, };
typedef std::vector<int> VecPath;
struct FuncState { VecPath path; };

int sum_value(const VecPath& path) {
int sum = 0;
for (unsigned int i = 0; i < path.size(); i++) {
sum += numbers[path[i]];
}
return sum;
}

void print_path(const VecPath& path) {
for (unsigned int i = 0; i < path.size(); i++) {
printf("%d ", numbers[path[i]]);
}
printf("\n");
}

Result check_next(const VecPath& path, int index) {
if (index >= num_length)
return INVALID_INDEX;
int sum = sum_value(path) + numbers[index];
return sum == target ? EQUAL : (sum > target ? LARGER : SMALLER);
}

void resolve() {
int current = 0;
bool done = false;

std::stack<FuncState> func_stack;
func_stack.push(FuncState());

do
{
/*numbers数组从左到右的顺序依次尝试; a~i表示下标索引 */
FuncState& fs = func_stack.top();
Result res = check_next(fs.path, current);
switch (res) {
case EQUAL: {
fs.path.push_back(current);  /*找到一条可用的路径*/
print_path(fs.path);
result_num++;

/*如满足的path为 a->e,将path弹出e,并继续检测f节点*/
fs.path.pop_back();
current++;
break;
}
case LARGER: {
current++;  /*过大,尝试下个节点*/
break;
}
case SMALLER: {
/*过小,添加到path,当前state不变,并压入新state,用于回溯; 但若已经是最后一个节点,不再添加到路径;
如当前stack为
[0] a
检测到 a->e 之和不足,stack更新为
[1] a->e
[0] a
并继续处理f节点 */
if (current != num_length - 1) {
FuncState newfs = fs;
newfs.path.push_back(current);
func_stack.push(newfs);
}
current++;
break;
}
case INVALID_INDEX: {
/*没有可作为路径第一个节点的节点,相当于1~9都曾经作为路径第一个节点处理过,停止循环*/
if (fs.path.empty()) {
done = true;
}
else {
/*当前path不可用,恢复到上个state,并继续往下处理,如当前stack为:
[2] a->e->f
[1] a->e
[0] a
检测发现 a->e->f-> 不通,恢复为 a->e,并从g开始*/
current = fs.path.back() + 1;
func_stack.pop();
}
break;
}
default: break;
}
} while (!done);
}

int get_result_num() { return result_num; }

private:
int* numbers;
int num_length;
int target;
int result_num;
};

void test1() {
int array[] = {
2, 3, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70 };

time_t startTime = time(NULL);
SumCombine sc(array, sizeof(array) / sizeof(int), 20);
sc.resolve();
printf("result_num=%d, usetime=%d\n", sc.get_result_num(), (int)(time(NULL) - startTime));
}

void test2() {
int array[] = { 9, 5, 2, 3, 4, 1, 7, 6, 8 };

time_t startTime = time(NULL);
SumCombine sc(array, sizeof(array) / sizeof(int), 16);
sc.resolve();
printf("result_num=%d, usetime=%d\n", sc.get_result_num(), (int)(time(NULL) - startTime));
}

int main() {
test1();
test2();
getchar();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐