4
\$\begingroup\$
int combiset(int ism,int inarr[],int inpth){
    int r1,r2,r3,r4;
    for(int i=0;i<inpth;i++){
        r1 = inarr[i]+inarr[i+1];
        r2 = r1+inarr[i+2];
        r3 = r2+inarr[i+3];
        r4 = r3+inarr[i+4];
        
        if(r4==ism){
            printf("%d %d %d %d %d\n",inarr[i],inarr[i+1],inarr[i+2],inarr[i+3],inarr[i+4]);}
        if(r3==ism){
            printf("%d %d %d %d\n",inarr[i],inarr[i+1],inarr[i+2],inarr[i+3]);}
        if(r2==ism){
            printf("%d %d %d\n", inarr[i], inarr[i+1], inarr[i+2]);}
        if(r1==ism){
            printf("%d %d\n", inarr[i], inarr[i+1]);}
    }
}

I am currently designing a function which will calculate and display out the possible combinations of sets from the user input. User will inputs the value of sum that they want to target and the array data such as length and integers inside. For example, if user inputs

array length:10
array data:9 1 5 5 8 9 7 3 1 6
target sum:10

then the result output should look like

9 1
5 5
7 3
3 1 6

Hereby, answer should follow the input array order and answers should be linked, so 1 5 3 1 cannot be an answer.

In my opinion, function which I have designed is too inefficient because user may input the array length as 100 then I have to make r1 until r100 to check whether there is possible combination of sets but with my method, the codes will get tremendously longer. Thus I am thinking of simpler code but I have no idea for it. How can I make my function better to find possible combinations of set?

\$\endgroup\$
0

1 Answer 1

6
\$\begingroup\$

Avoid repetition

Whenever you are repeating yourself twice or more often, you should immediately find some way to get rid of the repetition. You probably already know how to do this. For example, in this case, just add more for-loops: one to calculate the sum, and another to print all the elements once you have found a set of consecutive elements that sums up to the desired value:

for (int i = 0; i < inpth; i++) {
    int sum = 0;

    for (int j = i; j < inpth && sum < ism; j++) {
        sum += inarr[j];

        if (sum == ism) {
            // Now I know that the sum of element i to j equals ism
            for (int k = i; k <= j; k++) {
                 printf("%d ", inarr[k]);
            }

            printf("\n");
        }
    }
}

Create functions to solve smaller problems

Try to split up your problem in smaller problems, and write functions to solve the smaller problems. This allows you to focus on the smaller problems, and the code usually becomes more readable as well. For example:

/* Print out a single subset */
static void print_subset(int subarr[], int len) {
    for (int i = 0; i < len; i++) {
        printf("%d ", subarr[i]);
    }

    printf("\n");
}

/* Check if summing from the start of the subarray will get us the desired value */
static void check_subset(int ism, int subarr[], int len) {
    int sum = 0;

    for (int i = 0; i < len && sum < ism; i++) {
        sum += subarr[i];

        if (sum == ism) {
            print_subset(subarr, i + 1);
        }
    }
}

/* Check all possible subsets of the input array */
int combiset(int ism, int inarr[], int inpth) {
    for (int i = 0; i < inpth; i++) {
        check_subset(ism, inarr + i, inpth - i);
    }
}

In the above, each function only has a single for-loop, which makes them much easier to reason about than the three nested for-loops in the first example I gave.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.