C 修改给定的数字以找到所需的总和?
我的一个朋友问我这个问题。我还没能想出任何一种算法来解决这个问题 我们为您提供了一个编号,比如说C 修改给定的数字以找到所需的总和?,c,algorithm,math,sum,puzzle,C,Algorithm,Math,Sum,Puzzle,我的一个朋友问我这个问题。我还没能想出任何一种算法来解决这个问题 我们为您提供了一个编号,比如说123456789,以及两个操作员*和+。现在,在不更改所提供编号的顺序并根据需要多次使用这些运算符的情况下,计算给定值: 例如:给定值2097 解决方案:1+2+345*6+7+8+9 关于如何处理这些问题,有什么想法吗?没有那么多解决方案——这个python程序只需不到一秒钟的时间就可以将它们全部强制执行 from itertools import product for q in produc
123456789
,以及两个操作员*和+
。现在,在不更改所提供编号的顺序并根据需要多次使用这些运算符的情况下,计算给定值:
例如:给定值2097
解决方案:
1+2+345*6+7+8+9
关于如何处理这些问题,有什么想法吗?没有那么多解决方案——这个python程序只需不到一秒钟的时间就可以将它们全部强制执行
from itertools import product
for q in product(("","+","*"), repeat=8):
e = ''.join(i+j for i,j in zip('12345678',q))+'9'
print e,'=',eval(e)
下面是一个通过grep运行的示例
$ python sums.py | grep 2097
12*34+5*6*7*8+9 = 2097
12*3*45+6*78+9 = 2097
1+2+345*6+7+8+9 = 2097
一般的解决方案是一个简单的修改
from itertools import product
def f(seq):
for q in product(("","+","*"), repeat=len(seq)-1):
e = ''.join(i+j for i,j in zip(seq[:-1],q))+seq[-1]
print e,'=',eval(e)
最简单的方法之一是在BASH中使用shell扩展: #!/bin/sh for i in 1{,+,*}2{,+,*}3{,+,*}4{,+,*}5{,+,*}6{,+,*}7{,+,*}8{,+,*}9; do if [ $(( $i )) == 2097 ]; then echo $i = 2097 fi done #!/垃圾箱/垃圾箱 对于1{,+,*}2{,+,*}3{,+,*}4{,+,*}5{,+,*}6{,+,*}7{,+,*}8{,+,*}9中的i;做 如果[$($i))==2097];然后 echo$i=2097 fi 完成 其中: $ sh -c '. ./testequation.sh' 12*34+5*6*7*8+9 = 2097 12*3*45+6*78+9 = 2097 1+2+345*6+7+8+9 = 2097 $sh-c'/测试方程 12*34+5*6*7*8+9 = 2097 12*3*45+6*78+9 = 2097 1+2+345*6+7+8+9 = 2097
这不是最简单的方法,但我尝试编写“优化”代码:生成所有3^(n-1)字符串的代价很高,而且需要对其中的许多字符串进行评估;我仍然使用了bruteforce,但是切割了非生产性的“子树”(正如标题中所要求的,源代码是C)
#包括“stdio.h”
#包括“stdlib.h”
#包括“string.h”
#包括“math.h”
#定义B 10
void rec_solve(char*,char*,int,char,int,char,int,char*);
int main(int argc,字符**argv){
char*n,*si=malloc(0);
如果(argc<2){
printf(“使用:%s num sum”,argv[0]);
}否则{
n=calloc(strlen(argv[1]),sizeof(char));
strncpy(n,argv[1],strlen(argv[1]);
rec_solve(n,si,0,'+',0,'+',atoi(argv[2]),n);
}
返回0;
}
void rec_solve(char*str,char*sig,int p,char ps,int l,char ls,int max,char*or){
int i,len=strlen(str),t=0,siglen=strlen(sig),j,k;
char*mul;
字符*添加;
char*sub;
如果(p+l最大值)
打破
sub=calloc(len-i-1,sizeof(char));
strncpy(sub,str+i+1,len-i-1);
mul=calloc(siglen+i+1,sizeof(char));
strncpy(mul,sig,siglen);
add=calloc(strlen(sig)+i+1,sizeof(char));
strncpy(添加、标记、标记);
对于(j=0;j
这里是一个非递归Cbruteforce版本的实现,它适用于任何一组数字(合理的值在32位范围内,而不仅仅是上面的示例)。现在完成。:)
#包括
#包括
#包括
/*简单整数pow()函数*/
整数功率(整数基,整数功率)
{
int i,res=1;
对于(i=0;i#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "math.h"
#define B 10
void rec_solve(char *, char *, int, char, int, char, int, char *);
int main(int argc, char** argv) {
char *n, *si = malloc(0);
if (argc < 2) {
printf("Use : %s num sum", argv[0]);
} else {
n = calloc(strlen(argv[1]), sizeof (char));
strncpy(n, argv[1], strlen(argv[1]));
rec_solve(n, si, 0, '+', 0, '+', atoi(argv[2]), n);
}
return 0;
}
void rec_solve(char *str, char *sig, int p, char ps, int l, char ls, int max, char *or) {
int i, len = strlen(str), t = 0, siglen = strlen(sig), j, k;
char *mul;
char *add;
char *sub;
if (p + l <= max) {
if (len == 0) {
k = (ls == '+') ? p + l : p*l;
if ((k == max) && (sig[strlen(sig) - 1] == '+')) {
for (i = 0; i < strlen(or) - 1; i++) {
printf("%c", or[i]);
if (sig[i] && (sig[i] != ' '))
printf("%c", sig[i]);
}
printf("%c\n", or[i]);
}
} else {
for (i = 0; i < len; i++) {
t = B * t + (str[i] - '0');
if (t > max)
break;
sub = calloc(len - i - 1, sizeof (char));
strncpy(sub, str + i + 1, len - i - 1);
mul = calloc(siglen + i + 1, sizeof (char));
strncpy(mul, sig, siglen);
add = calloc(strlen(sig) + i + 1, sizeof (char));
strncpy(add, sig, siglen);
for (j = 0; j < i; j++) {
add[siglen + j] = ' ';
mul[siglen + j] = ' ';
}
add[siglen + i] = '+';
mul[siglen + i] = '*';
switch (ps) {
case '*':
switch (ls) {
case '*':
rec_solve(sub, add, p*l, '*', t, '+',max, or);
rec_solve(sub, mul, p*l, '*', t, '*',max, or);
break;
case '+':
rec_solve(sub, add, p*l, '+', t, '+',max, or);
rec_solve(sub, mul, p*l, '+', t, '*',max, or);
break;
}
case '+':
switch (ls) {
case '*':
rec_solve(sub,add,p, '+',l*t,'+',max, or);
rec_solve(sub,mul,p, '+',l*t,'*',max, or);
break;
case '+':
rec_solve(sub,add,p + l,'+',t,'+',max, or);
rec_solve(sub,mul,p + l,'+',t,'*',max, or);
break;
}
break;
}
}
}
}
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* simple integer pow() function */
int pow(int base, int pow)
{
int i, res = 1;
for (i = 0; i < pow; i++)
res *= base;
return res;
}
/* prints a value in base3 zeropadded */
void zeropad_base3(int value, char *buf, int width)
{
int length, dif;
_itoa(value, buf, 3);
length = strlen(buf);
dif = width - length;
/* zeropad the rest */
memmove(buf + dif, buf, length+1);
if (dif)
memset(buf, '0', dif);
}
int parse_factors(char **expr)
{
int num = strtol(*expr, expr, 10);
for ( ; ; )
{
if (**expr != '*')
return num;
(*expr)++;
num *= strtol(*expr, expr, 10);
}
}
/* evaluating using recursive descent parser */
int evaluate_expr(char* expr)
{
int num = parse_factors(&expr);
for ( ; ; )
{
if (*expr != '+')
return num;
expr++;
num += parse_factors(&expr);
}
}
void do_puzzle(const char *digitsString, int target)
{
int i, iteration, result;
int n = strlen(digitsString);
int iterCount = pow(3, n-1);
char *exprBuf = (char *)malloc(2*n*sizeof(char));
char *opBuf = (char *)malloc(n*sizeof(char));
/* try all combinations of possible expressions */
for (iteration = 0; iteration < iterCount; iteration++)
{
char *write = exprBuf;
/* generate the operation "opcodes" */
zeropad_base3(iteration, opBuf, n-1);
/* generate the expression */
*write++ = digitsString[0];
for (i = 1; i < n; i++)
{
switch(opBuf[i-1])
{
/* case '0' no op */
case '1': *write++ = '+'; break;
case '2': *write++ = '*'; break;
}
*write++ = digitsString[i];
}
*write = '\0';
result = evaluate_expr(exprBuf);
if (result == target)
printf("%s = %d\n", exprBuf, result);
}
free(opBuf);
free(exprBuf);
}
int main(void)
{
const char *digits = "123456789";
int target = 2097;
do_puzzle(digits, target);
return 0;
}
12*34+5*6*7*8+9 = 2097
12*3*45+6*78+9 = 2097
1+2+345*6+7+8+9 = 2097
1 (something) 9 = 10
1*9=10 - false
1/9=10 - false
1-9=10 - false
1+9=10 - True