Hello! How can I set a loop range with a double condition? For example, if zone == 0 , then the i cycle should run in the range (i < 6 && i > 19) , if zone == 1 , then (i > 6 && i < 19) , well, and if zone == 2 then for all i .

  for(int zone = 0; zone < nzones; zone++){ Gr[izone] = 0; for(i = 0; i < 26; i++){ for(int side = 0; side < 2; side++){ for(int run = 0; run < 2; run++){ for(int ell = 0; ell < 40; ell++){ Gr[izone] += Gr[i][side][run][ell]; } } } } 
  • try using if or switch. - KoVadim
  • The lower and upper bounds for i<6 && i>19 are not clear. And the 4-dimensional array Gr[i][side][run][ell] is too much. - αλεχολυτ
  • The bottom i = 0, and the top i = 25. Well, the array is the files that need to be divided along the sides, direction and cells with data inside - dopecat

5 answers 5

  1. We do a cycle over the whole range [0, 25) ;
  2. We get a function of the index and the zone, which returns true if the element requires processing;
  3. Combine it all.

 bool use(int zone, int i) { switch(zone) { case 0: return i < 6 || i > 19; case 1: return i > 6 && i < 19; default: return true; } } for(int i = 0; i < 25; ++i) { if(use(zone, i)) { // обрабатываем элемент } } 

To reduce the number of iterations, you can use a different approach: return the next index for each pair {index, zone}.

 int inc(int zone, int i) { ++i; switch(zone) { case 0: { if(i >= 6 && i <= 19) { i = 20; // следующий после разрыва } break; } case 1: { if(i < 6) { i = 6; } else if(i > 19) { i = 25; // последний в диапазоне } } } return i; } 

In essence, this will be a preliminary implementation of the idea of ​​iterators, which was suggested by @ igor-karpenko in its response.

 for(int i = 0; i < 25; i = inc(zone,i) { // обрабатываем элемент } 

PS All "magic" constants should, of course, be replaced by the named. In general, you should not take the proposed code as ready for implementation. This is just a sketch to demonstrate the idea.

  • The downside is that it sorts through all the possible options. For 25 iterations of nonsense, of course, but ... - Harry
  • Not the best option, because it will be spent on CPU time to call a function. - Vyacheslav Savchenko
  • @Harry, but everything is very clear. To reduce the number of iterations finalized the answer. - αλεχολυτ
  • @ VyacheslavSavchenko processor time makes sense to evaluate the appropriate utilities. The code must first be understood by the programmer. And premature optimization is the root of all evil. - αλεχολυτ

Well, if the ranges were inseparable (not like at zone==0 ), then it would be simple:

 for(int zone=0; zone < nzones; zone++) { for(i = (zone == 1) ? 7 : 0; i < (zone == 1) ? 19 : 26; i++) { } } 

But it will be necessary to process a discontinuous range either with two for , or one for for the entire range with a check, such as:

 for(int zone=0; zone < nzones; zone++) { for(i = (zone == 1) ? 7 : 0; i < (zone == 1) ? 19 : 26; i++) { if ((zone == 0) && (i >= 6) && (i <=19)) continue; ... } } 

It’s better to invent something without thinking ... Of course, in terms of efficiency, it’s better to paint three separate cases and not to waste time on checking at each iteration ...

     a = 0; b = 27; if (zone == 1) a = 6; for (int i = a; i < b+1; ) { //Ваши вычисления i++; if (zone == 0 && i == 6) i = 19; if (zone == 1 && i == 20) break; } 
    • Setting boundaries is hindered by a gap in the range For example, for the zero zone: 0-5, 20-25. - αλεχολυτ
    • @alexolut oh, duck, that's what it was, but what's stopping the "jump" in the cycle? - Vyacheslav Savchenko
    • @dopecat Author, provide a complete TK in terms of boundaries, then I can write down how to do. - Vyacheslav Savchenko
    • @ VyacheslavSavchenko So, the first border at zone == 0 the variable of the cycle runs from (i = 0; i <6) and (i> 19; i <26). With zone == 1 (i> 6; i <20). And finally, when zone == 2 (i = 0; i <26). For each case, the resulting amount Gr [zone] is divided into 608, 880, and 1488, respectively. In fact, the method proposed by Mr. alexolut gave the desired result (for which many thanks to him), but your proposal is also interesting. - dopecat
    • @dopecat I hope I understand you correctly, edited the answer. - Vyacheslav Savchenko

    I’m not sure if this is appropriate for your case, but I would describe a class that would encapsulate the iteration algorithm and redefine the getIterator() method, which would return a suitable range i for a particular instance.

      As a variant of checking known ranges, several ranges over 2 can be set here.

       enum { ZONE_1 = 0, ZONE_2, AMOUNT_ZONE } #define SIZE_ZONE 5 int array_zone[SIZE_ZONE] = {ZONE_1,ZONE_1,ZONE_2,ZONE_1,ZONE_1}; #define CHECK_ZONE_1 (ZONE_1+ZONE_1) #define CHECK_ZONE_2 (ZONE_1+ZONE_2) check_zone(int zone) { int i; for(i = 0;i<SIZE+ZONE;i++){ int z = array_zone[i] + zone; switch(z){ case (CHECK_ZONE_1): /*zone 1*/ break; case (CHECK_ZONE_2); /*zone 2*/ break default: /*all zone*/ break; } } } check_zone(ZONE_1);