blink
blink

Reputation: 49

Is there a way to accmplish the following loop without all the repetitive if statements?

The following is to fill out the values for a histogram:

for(index=0; index<256; index++) {
         while(1) {
             if(store[index] < bin_edge[1]) {
                 bins[0]++;
                 break;
             }
             if(store[index] < bin_edge[2]) {
                 bins[1]++;
                 break;
             }
             if(store[index] < bin_edge[3]) {
                 bins[2]++;
                 break;
             }
             if(store[index] < bin_edge[4]) {
                 bins[3]++;
                 break;
             }
             if(store[index] < bin_edge[5]) {
                 bins[4]++;
                 break;
             }     
             if(store[index] < bin_edge[6]) {
                bins[5]++;
                break;
             }
             if(store[index] < bin_edge[7]) {
                bins[6]++;
                break;
             }
             if(store[index] < bin_edge[8]) {
                bins[7]++;
                break;
             }
             if(store[index] < bin_edge[9]) {
                bins[8]++;
                break;
             }
             if(store[index] < bin_edge[10]) {
                bins[9]++;
                break;
             }
             if(store[index] < bin_edge[11]) {
                bins[10]++;
                break;
             }
             if(store[index] < bin_edge[12]) {
                bins[11]++;
                break;
             }
             if(store[index] < bin_edge[13]) {
                bins[12]++;
                break;
             }
             if(store[index] < bin_edge[14]) {
                bins[13]++;
                break;
             }
             if(store[index] < bin_edge[15]) {
                bins[14]++;
                break;
             }
                bins[15]++;                       /* Default case */
                break;
         }
     }

store is an integer array I am graphing, bins array is the graph values, bin_edge array holds the right hand edge of each bin. I admit to being a novice at the "c" language". This works but is clumsy and tedious to code.

Upvotes: 0

Views: 84

Answers (4)

mj420
mj420

Reputation: 258

Replace all those if statements with a single for loop:

for (index = 0; index < 256; index++) {
    while (1) {
        for (size_t i = 1; i < 16; i++) {
            if (store[index] < bin_edge[i]) {
                bins[i - 1]++;
                goto outer_for;
            }
        }
        bins[15]++;
        break;
    }
    outer_for: ;
}

Which can be simplified:

for (index = 0; index < 256; index++) {
    for (size_t i = 1; i < 16; i++) {
        if (store[index] < bin_edge[i]) {
            bins[i - 1]++;
            goto no_default;
        }
    }
    bins[15]++;
    no_default: ;
}

Flag instead of goto:

for (index = 0; index < 256; index++) {
    int default_flag = 1;
    for (size_t i = 1; i < 16; i++) {
        if (store[index] < bin_edge[i]) {
            bins[i - 1]++;
            default_flag = 0;
            break;
        }
    }
    if (default_flag) {
        bins[15]++;
    }
}

Upvotes: 0

Craig Estey
Craig Estey

Reputation: 33621

I guess this is a competition for the most efficient replacement loop :-)

Here's yet another one (assuming int, but set type of curval to whatever the type of store is) ...

for (index = 0; index < 256; index++) {
    int curval = store[index];
    int edgeidx;

    for (edgeidx = 1;  edgeidx <= 15;  ++edgeidx) {
        if (curval < bin_edge[edgeidx])
            break;
    }

    bins[edgeidx - 1]++;
}

Upvotes: 1

kaylum
kaylum

Reputation: 14046

Can have an inner for loop that iterates over bin_edge:

for(index=0; index<256; index++) {
    for (bin_ix = 1; bin_ix < 16; bin_ix++) {
        if(store[index] < bin_edge[bin_ix]) {
            bins[bin_ix-1]++;
            break;
        }
    }
    if (bin_ix == 16) {
         bins[bin_ix-1]++;
    }
}

Upvotes: 0

fas
fas

Reputation: 1413

Add one more inner cycle and indicator whether case in non-default:

for (index = 0; index < 256; index++) {
     int bin_incremented = 0;  // indicator
     for (int bin_index = 0; bin_index < 15; bin_index++) {
         if(store[index] < bin_edge[bin_index + 1]) {
             bins[bin_index]++;
             bin_incremented = 1;
             break;
         }
     }
     if (!bin_incremented) {
          bins[15]++;
     }
 }

Upvotes: 2

Related Questions