Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

232
Visualizações
C function to get all sums of an array using addition and subtraction

What would be the best way (in C) to get all sums of N numbers in an array, by using addition and subtraction?

For example (N = 3):

arr[] = [30, 14, 2]

results:
-30-14-2 = -46
-30-14+2 = -42
-30+14-2 = -18
-30+14+2 = -14
 30-14-2 = 14
 30-14+2 = 18
 30+14-2 = 42
 30+14+2 = 46

As can be seen, there are 2^N solutions.

I also noticed that the addition an subtraction symbols alternate in the same way as binary counting (000 001 … 110 111), which might be useful.

Probably a recursive approach would be best, but I find it very hard to think recursively.

Therefore, I hope someone can explain to me what the best strategy would be to tackle this problem.

——————————

EDIT:

I have a working Python code, but this uses sets set(), which aren’t available in C. (arr is an array containing all numbers.)

out = set()
out.add(0)
for i in range(0, len(arr)):
    tmp = set()
    for j in out:
        tmp.add(j + arr[i])
        tmp.add(j - arr[i])
    out = tmp
print(out)

——————————

EDIT:

With replacing the sets by arrays and making a few small changes, I got it working. Thanks to everyone who commented!

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

This is a case where recursion seems preferable to a data structure because the exponential nature of the problem means there's no risk of a stack overflow on any value of n you could realistically test, yet you can take advantage of the stack's implicit storage capabilities.

The recursive logic can be written very directly using an index i. The base case is when i >= n; print the sum you've accumulated. Otherwise, subtract the ith element from the sum and recurse on the rest of the numbers list without i. In a second branch, add the ith element to the sum and recurse on the rest of the numbers list without i. You could also shift elements off the array using a pointer instead if i as pointed out in the comments.

Note that this procedure will include duplicate results, so if you want to eliminate those, your original set idea is worth pursuing.

It's generally poor design to mix IO and logic in functions, but for simplicity's sake, I'll break that rule here:

#include <stdio.h>

void print_possible_sums(int nums_len, int *nums, int sum, int i) {
    if (i >= nums_len) {
        printf("%d\n", sum);
    }
    else {
        print_possible_sums(nums_len, nums, sum - nums[i], i + 1);
        print_possible_sums(nums_len, nums, sum + nums[i], i + 1);
    }
}

int main() {
    int arr[] = {30, 14, 2};
    print_possible_sums(sizeof(arr) / sizeof(arr[0]), arr, 0, 0);
    return 0;
}

Output:

-46
-42
-18
-14
14
18
42
46
over 4 years ago · Santiago Trujillo Relatório

0

I have made an algorithm that performs this problem. Maybe what I wrote is not as efficient as possible (so maybe it can be improved) but at least it works.

Let me know if it's okay.

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

#define MAX 4
void cycle(int arr[MAX]);
int toRepeat(int arr[MAX], int s);

int main(){
    int arr[MAX] = {1, 2, 3, 4};
    cycle(arr);
}

void cycle(int arr[MAX]){
    int a, ris;
    a = pow(2, MAX);
    for (int i= 0; i < a; i++){
        ris = toRepeat(arr, i);
        printf(" = %3d \n", ris);
    }
}

int toRepeat(int arr[MAX], int s){
    int pos = 0;
    int ris = 0;
    int a;
    bool flag;
    a = pow(2, MAX);
    if (s < a/2) {
        ris += arr[pos];
        printf("+%d", arr[pos]);
    } else {
        ris -= arr[pos];
        printf("-%d", arr[pos]);
    }
    pos++;
    
    for (int i= 2; i < a; i = i * 2){
        for (int j= 0; j < i/2; j++) {
            if (s%i == j) {
                ris += arr[pos];
                printf("+%d", arr[pos]);
                pos++;
                flag = true;
                break;
            }
        }
        if (!flag){
            ris -= arr[pos];
            printf("-%d", arr[pos]);
            pos++;
        }
        flag = false;
    }
    return ris;
}

Output:

+1+2+3+4 =  10
+1-2+3+4 =   6
+1+2-3+4 =   4
+1-2-3+4 =   0
+1+2+3-4 =   2
+1-2+3-4 =  -2
+1+2-3-4 =  -4
+1-2-3-4 =  -8
-1+2+3+4 =   8
-1-2+3+4 =   4
-1+2-3+4 =   2
-1-2-3+4 =  -2
-1+2+3-4 =   0
-1-2+3-4 =  -4
-1+2-3-4 =  -6
-1-2-3-4 = -10
over 4 years ago · Santiago Trujillo Relatório

0

Me too, me too!

Keep one array with bool negative[3 + 1] = {0};. Calculate sum of array[i] * (negative[i]?-1:1) at each step. Each step increments the next value in negative as if it would be a binary number. The loop ends when the highest element negative[3] is true - so we want through all possibilities.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>

int calc_sum(size_t len, const int vals[len], const bool negative[len]) {
    int sum = 0;
    for (size_t i = 0; i < len; ++i) {
        sum += vals[i] * (negative[i] ? -1 : 1);
    }
    return sum;
}

bool *sequence_init(size_t len) {
    // error checking omitted
    return calloc(len + 1, sizeof(bool));
}

bool sequence_continue(size_t len, bool t[len + 1]) {
    assert(t);
    const bool go_on = !t[len];
    if (!go_on) {
        // automatically free on loop end
        free(t);
    }
    return go_on;
}

void sequence_next(size_t len, bool t[len + 1]) {
    assert(t);
    for (size_t i = 0; i < len + 1; ++i) {
        if (!t[i]) {
            t[i] = 1;
            break;
        } else {
            t[i] = 0;
        }
    }
}

int main() {
    const int vals[3] = { 30, 14, 2 };
    const size_t len = 3;
    for(
        bool *sequence = sequence_init(len);
        sequence_continue(len, sequence);
        sequence_next(len, sequence)
    ) {
        for (size_t i = 0; i < len; ++i) {
            printf("%2d*%d %c ",
                sequence[i]?-1:1,
                vals[i],
                i + 1 != len ? '+' : '='
            );
        }
        const int sum = calc_sum(len, vals, sequence);
        printf("%d\n", sum);
    }
}

The code outputs:

 1*30 +  1*14 +  1*2 = 46
-1*30 +  1*14 +  1*2 = -14
 1*30 + -1*14 +  1*2 = 18
-1*30 + -1*14 +  1*2 = -42
 1*30 +  1*14 + -1*2 = 42
-1*30 +  1*14 + -1*2 = -18
 1*30 + -1*14 + -1*2 = 14
-1*30 + -1*14 + -1*2 = -46
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda