快速求和递归的递归没有得到正确的结果
Not getting proper result with my recursion for quick sum recursion
给定一串数字,找到使该字符串等于某个目标数字所需的最少加法次数。每次加法都相当于在数字串的某处插入一个加号。
示例:
“1110”
目标 3
return 3 因为 1+1+1+0=3 需要 3 次加法。
"0123456789"
目标 45
Returns: 8
"99999"
目标 100
Returns:-1
"382834"
100
Returns: 2
100有3种方法,分别是38+28+34、3+8+2+83+4、3+82+8+3+4。最少需要 2 个。
我试过这个问题,这是我的代码。我第一次考虑一个角色并得到结果。下次我使用 2 个字符并获得结果时,依此类推,直到我尝试了最大 string.I 大小的所有字符,我没有得到正确的递归。
int min(int a,int b)
{
return a>b?b:a;
}
/* i is current index we are considering and sum is total number
*of + required
*/
int foo(char *a, int size, int i, int current_stock, int target, int sum){
unsigned long long int mini = 1 << 30; /* huge number */
int number=0, mul, m;
int p = i;
if (i+current_stock>size)
return mini;
if (target == 0)
return sum;
if (target < 0)
return mini;
mul = 1;
/* make the multiplier */
for (m=1;m<current_stock;m++) {
mul *= 10;
}
/* make the number from i to current_stock
* if the string is 123 and if i is 0 and current_stock is 2
* then the number will be 12 */
for (m=0;m<current_stock;m++) {
number += (a[p]-'0')*mul;
mul = mul/10;
p++;
}
sum = sum + 1;
for(m=current_stock;m<=size;m++) {
mini = min(mini, foo (a, size, i+current_stock, m, target-number, sum));
}
return mini;
}
int main(void) {
char a[] = "382834";
printf("%d", foo(a, strlen(a), -1, 1, 100, 0));
printf("%d\n", strlen(a));
return 0;
}
我编写了您提到的确切解决方案,它似乎对我有用。只是一个变化,你不需要去到所有的角色,如果你已经越过了目标然后就可以提前打破。
#define INFINITY 100000
long int result[20][1000];
long int solve(char *str,long int i,long int target){
long int min=INFINITY;
long int number=0,base=10;
long int j=i;
long int score1;
//memoized result
if(result[i][target]!=-2){
return result[i][target];
}
//if target is achieved and string is finished
if(i==strlen(str) && target==0){
return 0;
}
// if string finished but target not achieved
if(i==strlen(str)&& target!=0){
return -1;
}
while(j<strlen(str)){
long int digit=str[j]-'0';
number=number*base+digit;
if(number <=target){
score1=solve(str,j+1,target-number);
if(score1!=-1){
if(j<(strlen(str)-1))
score1=score1+1;
if(score1<min){
min=score1;
}
}
}
else{
break;
}
j++;
}
if(min<INFINITY)
result[i][target]=min;
else
result[i][target] = -1;
return result[i][target];
}
对于非计算值,我正在用 -2 初始化我的记忆数组结果。我检查了所有给出的测试用例,它正在工作。请检查解决方案,让我知道它是否有意义。
我想@Naman 给你找到了解决方案,但你工作太辛苦了。只需将第一个加号放在每个可能的位置,然后重复放置其余的。基本情况是所有数字都等于目标。在这种情况下,所需的加数为零。
#include <stdio.h>
#include <string.h>
#define NO_SOLUTION (-1)
int find_min_plusses(int target, char *digits, int n_digits) {
int min = NO_SOLUTION, val = 0, i;
for (i = 0; i < n_digits - 1; i++) {
val = val * 10 + (digits[i] - '0');
if (val > target) return min;
int rest = find_min_plusses(target - val, digits + i + 1, n_digits - i - 1);
if (rest != NO_SOLUTION && (min == NO_SOLUTION || rest + 1 < min))
min = rest + 1;
}
val = val * 10 + (digits[i] - '0');
return val == target ? 0 : min;
}
int main(int argc, char *argv[]) {
int target;
if (argc == 3) {
if (sscanf(argv[1], "%d", &target) != 1) return 1;
int min = find_min_plusses(target, argv[2], strlen(argv[2]));
printf("%d\n", min);
}
return 0;
}
在这里你可以观看运行。每一行都是一个调用。
./a.out 100 382834
tgt=100,digits=382834,n_digits=6
tgt=97,digits=82834,n_digits=5
tgt=89,digits=2834,n_digits=4
tgt=87,digits=834,n_digits=3
tgt=79,digits=34,n_digits=2
tgt=76,digits=4,n_digits=1
tgt=4,digits=4,n_digits=1
tgt=61,digits=34,n_digits=2
tgt=58,digits=4,n_digits=1
tgt=15,digits=834,n_digits=3
tgt=7,digits=34,n_digits=2
tgt=4,digits=4,n_digits=1
tgt=62,digits=2834,n_digits=4
tgt=60,digits=834,n_digits=3
tgt=52,digits=34,n_digits=2
tgt=49,digits=4,n_digits=1
tgt=34,digits=34,n_digits=2
tgt=31,digits=4,n_digits=1
2
给定一串数字,找到使该字符串等于某个目标数字所需的最少加法次数。每次加法都相当于在数字串的某处插入一个加号。
示例: “1110”
目标 3
return 3 因为 1+1+1+0=3 需要 3 次加法。
"0123456789"
目标 45
Returns: 8
"99999"
目标 100
Returns:-1
"382834"
100
Returns: 2
100有3种方法,分别是38+28+34、3+8+2+83+4、3+82+8+3+4。最少需要 2 个。
我试过这个问题,这是我的代码。我第一次考虑一个角色并得到结果。下次我使用 2 个字符并获得结果时,依此类推,直到我尝试了最大 string.I 大小的所有字符,我没有得到正确的递归。
int min(int a,int b)
{
return a>b?b:a;
}
/* i is current index we are considering and sum is total number
*of + required
*/
int foo(char *a, int size, int i, int current_stock, int target, int sum){
unsigned long long int mini = 1 << 30; /* huge number */
int number=0, mul, m;
int p = i;
if (i+current_stock>size)
return mini;
if (target == 0)
return sum;
if (target < 0)
return mini;
mul = 1;
/* make the multiplier */
for (m=1;m<current_stock;m++) {
mul *= 10;
}
/* make the number from i to current_stock
* if the string is 123 and if i is 0 and current_stock is 2
* then the number will be 12 */
for (m=0;m<current_stock;m++) {
number += (a[p]-'0')*mul;
mul = mul/10;
p++;
}
sum = sum + 1;
for(m=current_stock;m<=size;m++) {
mini = min(mini, foo (a, size, i+current_stock, m, target-number, sum));
}
return mini;
}
int main(void) {
char a[] = "382834";
printf("%d", foo(a, strlen(a), -1, 1, 100, 0));
printf("%d\n", strlen(a));
return 0;
}
我编写了您提到的确切解决方案,它似乎对我有用。只是一个变化,你不需要去到所有的角色,如果你已经越过了目标然后就可以提前打破。
#define INFINITY 100000
long int result[20][1000];
long int solve(char *str,long int i,long int target){
long int min=INFINITY;
long int number=0,base=10;
long int j=i;
long int score1;
//memoized result
if(result[i][target]!=-2){
return result[i][target];
}
//if target is achieved and string is finished
if(i==strlen(str) && target==0){
return 0;
}
// if string finished but target not achieved
if(i==strlen(str)&& target!=0){
return -1;
}
while(j<strlen(str)){
long int digit=str[j]-'0';
number=number*base+digit;
if(number <=target){
score1=solve(str,j+1,target-number);
if(score1!=-1){
if(j<(strlen(str)-1))
score1=score1+1;
if(score1<min){
min=score1;
}
}
}
else{
break;
}
j++;
}
if(min<INFINITY)
result[i][target]=min;
else
result[i][target] = -1;
return result[i][target];
}
对于非计算值,我正在用 -2 初始化我的记忆数组结果。我检查了所有给出的测试用例,它正在工作。请检查解决方案,让我知道它是否有意义。
我想@Naman 给你找到了解决方案,但你工作太辛苦了。只需将第一个加号放在每个可能的位置,然后重复放置其余的。基本情况是所有数字都等于目标。在这种情况下,所需的加数为零。
#include <stdio.h>
#include <string.h>
#define NO_SOLUTION (-1)
int find_min_plusses(int target, char *digits, int n_digits) {
int min = NO_SOLUTION, val = 0, i;
for (i = 0; i < n_digits - 1; i++) {
val = val * 10 + (digits[i] - '0');
if (val > target) return min;
int rest = find_min_plusses(target - val, digits + i + 1, n_digits - i - 1);
if (rest != NO_SOLUTION && (min == NO_SOLUTION || rest + 1 < min))
min = rest + 1;
}
val = val * 10 + (digits[i] - '0');
return val == target ? 0 : min;
}
int main(int argc, char *argv[]) {
int target;
if (argc == 3) {
if (sscanf(argv[1], "%d", &target) != 1) return 1;
int min = find_min_plusses(target, argv[2], strlen(argv[2]));
printf("%d\n", min);
}
return 0;
}
在这里你可以观看运行。每一行都是一个调用。
./a.out 100 382834
tgt=100,digits=382834,n_digits=6
tgt=97,digits=82834,n_digits=5
tgt=89,digits=2834,n_digits=4
tgt=87,digits=834,n_digits=3
tgt=79,digits=34,n_digits=2
tgt=76,digits=4,n_digits=1
tgt=4,digits=4,n_digits=1
tgt=61,digits=34,n_digits=2
tgt=58,digits=4,n_digits=1
tgt=15,digits=834,n_digits=3
tgt=7,digits=34,n_digits=2
tgt=4,digits=4,n_digits=1
tgt=62,digits=2834,n_digits=4
tgt=60,digits=834,n_digits=3
tgt=52,digits=34,n_digits=2
tgt=49,digits=4,n_digits=1
tgt=34,digits=34,n_digits=2
tgt=31,digits=4,n_digits=1
2