计算几个数相加和为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; }
相关文章推荐
- Uva 数论&&计算几何 几个水题
- 10进制的四位数中有几个符合如下特征:将其分别表示为16进制、10进制、12进制,在每种状态下,分别将各个位上的数相加,能得到3个相等10进制数。输出所有符合这样特征的10进制的四位数。
- 16进制数据相加,计算校验和
- 最有效的计算2*16的方法——位运算(左移和右移)
- MyBatis学习总结(16)——Mybatis使用的几个建议
- 坚持#第215天~零基础自学云计算基础语言应用16~20节
- CCITT CRC-16计算原理与实现【整理综合】
- C# 计算CRC16
- php计算几分钟前、几小时前、几天前的几个函数、类功能实现
- 题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。 # 例如2+22+222+2222+22222(此时共有5个数相加),几个数相加由键盘控制。
- C100-18 题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时 共有5个数相加),几个数相加有键盘控制。
- 计算两个数相加时进位的个数
- 如何计算Oracle内存中的几个命中率
- C语言精度计算——大数相加
- 题目:求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。例如2+22+222+2222+22222(此时共有5个数相加),几个数相加有键盘控制。
- 编程练习:计算一个数的二进制形式含有几个1
- 仿脑计算需要注意的几个问题
- 程序员之---C语言细节20(符号和有符号之间转换、两数相加溢出后数值计算)
- 计算两个整数相加之和
- C++中用于科学计算的几个库