2011-12-19 66 views
0

對於N個(a..N)我發現所有組合的以下述方式設置:計算絕對值組合

void create_print_combinations(int *t, int x, int n) { 
    if(x == 0) { 
     char p [2 * r + 2]; 
     memset (p, 0, 2 * r +2); 
     for (int j=c;j>0;j--) 
      if(j == c) 
       sprintf(p, "%d", t[j]); 
      else 
       sprintf(p, "%s,%d", p,t[j]); 
      print_combi(p); 
    } else { 
     for (int i= n; i < r; i++) { 
      t[x] = a[i]; 
      create_print_combinations(t, x-1, i+1); 
     } 
    } 
} 

因此,一個呼叫類似功能

int main() { 
    unsigned long int start=0, end=0; 
    printf ("\nEnter the a positive integer N:"); 
    scanf("%d", &r); 
    start=time(NULL); 
    a = new int[r]; 
    for (int i = 0;i<r;i++) 
    a[i]=i+1; 
    for(int j=1;j<=r;j++) { 
     a1 = new int[j]; 
     c=j; 
     create_print_combinations(a1, c, 0); 
     delete[] a1; 
    } 
    end=time(NULL); 
    printf("Total time taken = %llu\n" , end - start); 
    return 0; 
} 

給我組合像N = 4:

輸入一個正整數N:4

Combo : [1] 
Combo : [2] 
Combo : [3] 
Combo : [4] 
Combo : [1,2] 
Combo : [1,3] 
Combo : [1,4] 
Combo : [2,3] 
Combo : [2,4] 
Combo : [3,4] 
Combo : [1,2,3] 
Combo : [1,2,4] 
Combo : [1,3,4] 
Combo : [2,3,4] 
Combo : [1,2,3,4] 

現在我的任務就是喜歡像所有組合的絕對值:

對於組合[1,2,3,4]應該是:

1+2+3+4 = abs(1+2+3+4) 
1+2+3-4 = abs(1+2+3-4) 
1+2-3-4 = .. 
1-2-3+4 = ... 

答案等

我想下面的邏輯:

while(pos > 0) 
{ 
for(int a=0; a < i; a++) 
{ 
if(a==0) 
sprintf(p,"%d", t[a]); 
else if(a == pos) 
sprintf(p,"%s%c%d",p, minus, t[a]); 
else 
sprintf(p,"%s%c%d",p, plus, t[a]); 
} 
print(p); 
memset (p , 0, 2 * r +2); 
pos --; 
} 

但我beleiev我做的事情錯了,因爲沒有得到所有打印設置。儘管我覺得我已接近完成,但我無法確定邏輯。下面是我的整個程序:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 
#include <time.h> 

int *a; 
int *a1; 
int r; 
int c; 
unsigned long int no =1; 

int stoi(char *var) 
{ 
int n1 = 0; 
int n2 = 0; 
int n3 = 0; 
char sign=0; 
while(*var) 
{ 
if(isspace(*var)) 
{ 
var++; 
continue; 
} 
while(*var >= '0' && *var <= '9') 
{ 
n1=(n1*10) + (*var - '0'); 
var++; 
continue; 
} 
if(sign == '+') 
{ 
n2=n2+n1; 
n1=0; 
} 
else if(sign == '-') 
{ 
n2=n2 - n1; 
n1=0; 
} 
if(*var == '+' || *var == '-') 
{ 
if(sign == 0) 
{ 
n2=n1; 
n1=0; 
} 
sign = *var; 
} 
var++; 
} 
if(sign == 0) 
return abs(n1); 
return abs(n2); 
} 

void print(char* var) 
{ 
printf("[Combo %llu.] %s = %d\n" , no++, var, stoi(var)); 
} 

void print_combi(char * a) 
{ 
int t[c]; 
char *x = NULL; 
char *y = a; 
int i=0; 
while((x=strchr(y, ',')) != NULL) 
{ 
*x = '\0'; 
t[i++]=atoi(y); 
y=x+1; 
} 
t[i++]=atoi(y); 
int count =0; 
int loop = 0; 
char p [2 * r + 2]; 
memset (p , 0, 2 * r +2); 
char plus = '+'; 
char minus = '-'; 
for(int k=0;k<2;k++) 
{ 
if(k==1) 
{ 
plus = '-'; 
minus = '+'; 
} 
if(i>1) 
{ 
for(int a=0; a < i; a++) 
{ 
if(a==0) 
sprintf(p,"%d", t[a]); 
else 
sprintf(p,"%s%c%d",p, plus, t[a]); 
} 
} 
else if(i==1) 
{ 
sprintf(p,"%d", t[i-1]); 
print(p); 
break; 
} 
print(p); 
memset (p , 0, 2 * r +2); 
if(i==2) 
continue; 
if(i==3 && k ==1) 
break; 
int pos = i-1; 
while(pos > 0) 
{ 
for(int a=0; a < i; a++) 
{ 
if(a==0) 
sprintf(p,"%d", t[a]); 
else if(a == pos) 
sprintf(p,"%s%c%d",p, minus, t[a]); 
else 
sprintf(p,"%s%c%d",p, plus, t[a]); 
} 
print(p); 
memset (p , 0, 2 * r +2); 
pos --; 
} 
} 
} 

void create_print_combinations(int *t, int x, int n) 
{ 
if(x == 0) 
{ 
char p [2 * r + 2]; 
memset (p, 0, 2 * r +2); 
for (int j=c;j>0;j--) 
if(j == c) 
sprintf(p, "%d", t[j]); 
else 
sprintf(p, "%s,%d", p,t[j]); 
print_combi(p); 
} 
else 
for (int i= n; i < r; i++) 
{ 
t[x] = a[i]; 
create_print_combinations(t, x-1, i+1); 
} 
} 
int main() 
{ 
unsigned long int start=0, end=0; 
printf ("\nEnter the a positive integer N:"); 
scanf("%d", &r); 
start=time(NULL); 
a = new int[r]; 
for (int i = 0;i<r;i++) 
a[i]=i+1; 
for(int j=1;j<=r;j++) 
{ 
a1 = new int[j]; 
c=j; 
create_print_combinations(a1, c, 0); 
delete[] a1; 
} 
end=time(NULL); 
printf("Total time taken = %llu\n" , end - start); 
return 0; 
} 

根據程序邏輯我計算組合作爲字符串和生成表達式的絕對值。

回答

0

爲@ SteveC的解決方案的某些代碼:

#include <iostream> 
#include <sstream> 
using namespace std; 
void print_sum(int N, int sum_so_far, string as_a_string) { 
     if(N) { 
       ostringstream oss; oss << N; 
       print_sum(N-1, sum_so_far+N, as_a_string + "+" + oss.str() + " "); 
       print_sum(N-1, sum_so_far-N, as_a_string + "-" + oss.str() + " "); 
       print_sum(N-1, sum_so_far, as_a_string); 
     } else { 
       if (sum_so_far < 0) sum_so_far *= -1; 
       cout << as_a_string << "\t= " << sum_so_far << endl;   } 
} 

int main() { 
     print_sum(4, 0, ""); 
} 

輸出開始:

+4 +3 +2 +1  = 10 
+4 +3 +2 -1  = 8 
+4 +3 +2  = 9 
+4 +3 -2 +1  = 6 
+4 +3 -2 -1  = 4 
+4 +3 -2  = 5 
+4 +3 +1  = 8 
+4 +3 -1  = 6 
# .. and so on 
+1

只需在頂部傳遞N,在遞歸調用中傳遞N-1。不需要x。還需要在結果上打印絕對值。 – 2011-12-19 18:52:39

+0

@SteveC,+1分優點。隨意將我的代碼複製到您的答案中,包括這些更改。你應該得到接受的答案!無論如何,我將在接下來的幾個小時內離線。 – 2011-12-19 18:56:01

+1

我確認你的解決方案。看起來不錯。 – 2011-12-19 19:25:18

0

你所要做的與列舉所有組合從「N選擇1」到「N選擇N」非常相似。我建議你在谷歌下的術語「枚舉組合」

這裏是我發現的一個環節搜索:

http://www.codeproject.com/KB/recipes/CombC.aspx

+0

是的,我能夠產生通過create_print_combinations方法編碼組合 - 我的問題是,我不能夠以獲得打印所有組合的絕對和的邏輯:類似於Combi 1,2,3:1 + 2 + 3,1 + 2-3,1-2 + 3,1-2-3。我的邏輯打破了一個更大的值,n = 10; – Prakash 2011-12-19 06:14:19

0

這裏是如何做到這一點邏輯。打印所有尺寸爲n-1的二進制數字,其中n是相應組合的大小(元素數量)。例如,要爲組合[1,2,3,4]創建所需的所有二進制組合,即3(n-1 = 3,這裏n = 4個元素)。即

when n = 3, the possible combinations are: 
000 
001 
010 
011 
100 
101 
110 
111 

現在運行在您的組合爲循環和裏面,只要你找到一個0做加法,只要你找到1做減法。例如,000意味着1+2+3+4101意味着1-2+3-4

1

有一個更簡單的方法來處理你在做什麼。要添加了N個整數的向量:

[1 * K1,2 * K2,3 * ... K3 N *千牛]

其中KX = -1,0,+ 1。

對於x = 1..N,有3^N個kx的組合。

+0

我想了解您在邏輯上想出的概念/方法,並將所需的代碼實現映射到它[如下所述]。我認爲這些是我需要掌握的技能。請以明確的方式提供一些意見,是否有一些細節可以談論它。我也看到了O(lonN)等概念,但實際上並不瞭解它。 – Prakash 2011-12-20 13:14:37

+0

您以向量[1,2,3,... N]開頭 您將N個元素的所有組合相當於乘以0或+1。然後,您將所有+1元素加上或減去,這與乘以+1或-1相同。我只注意到你可以一步到位。 – 2011-12-20 15:31:46