Есть ли лучший способ (математический/С++ трюк) Итерации вперед и назад в пределах заданного диапазона

Используя оператор модульной арифметики (или) (%) в C++, мы можем перебирать последовательные числа с диапазоном.

Например:

если диапазон равен 5 (или) по модулю 5, тогда мы можем перебирать

0 1 2 3 4 0 (5) 1(6) 2(7) 3(8) 4(9) 0(10)............0 1 2 3 и т.д.

Вопрос:

В аналогичном смысле существует ли какое-либо арифметическое отношение/трюк С++, который мы можем использовать для перемещения увеличивающихся чисел вперед (до верхней границы) и уменьшения чисел в обратном направлении (до нижней границы или 0) с диапазоном.

Например:

если диапазон = 5, то

0 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 0.....................0 1 2 3 и т.д.

В приведенной ниже программе я использовал два подхода для итерации вперед/назад в заданном диапазоне.

Но меня интересует: Есть ли лучший способ (трюк С++/Математическое отношение) итерации вперед и назад в заданном диапазоне?.

#include<iostream>
int main() {
    int range = 5;

    // 0 1 2 3 4 0 1 2 3 4 .....(Cycle through in the range 0 - 4)
    int i = 0;
    while(true) {
        // 0 1 2 3 4 0 1 2 3 4 .....(cycle through in the range 0 - 4)
        std::cout<< i; 
        i = (i+1)% range; // Modulo
        // some break condition
    }

    // 0 1 2 3 4 3 2 1 0 .......... (Forward and Reverse in the range 0 - 4)
    // Method 1:
    int j = 0;
    bool reverse = false;
    while(true) {
        if(reverse == false) {
            if(j < range) {
                std::cout << j;
                j = j+1;
            }
            else {
                reverse = true;
                j = j-1;
            }
        }
        else {
            j = j-1;
            std::cout << j;
            if(j == 0) {
                reverse = false;
                j = j + 1;
            }
        }
        // some break condition
    }

    // 0 1 2 3 4 3 2 1 0 .......... (Forward and Reverse in the range 0 - 4)
    // Method 2: 
    // Using modulo (if the range is big value then this is not good approach)
    int limit[8] = {0,1,2,3,4,3,2,1};
    int k = 0;
    while(true) {
        std::cout<< limit[k];
        k = (k+1)%8;
        // some break condition
    }
    return 0;
}

person SridharKritha    schedule 08.07.2014    source источник
comment
Вы сначала объясняете, как это сделать, а потом спрашиваете, как это сделать? Пожалуйста, измените свой вопрос и скажите, в чем ваша проблема...   -  person Deduplicator    schedule 08.07.2014
comment
Взгляните на функцию треугольной волны, а затем настройте и упростите (если возможно) для своей ситуации.   -  person Alan    schedule 08.07.2014


Ответы (2)


Вы можете использовать функцию абсолютного значения следующим образом:

int i = range;
int a = range;
while(true) {
// 0 1 2 3 4 3 2 1 0 .......... (Forward and Reverse in the range 0 - 4)
    a = abs(i-range);
    std::cout<< a; 
    i = (i+1)%(range*2); // Modulo
}

По сути, вы удваиваете диапазон, вычитаете половину диапазона (так что он идет от -диапазона до +диапазона), затем берете абсолютное значение.

РЕДАКТИРОВАТЬ: исправлен код для запуска с нуля вместо диапазона.

person Chris Bogart    schedule 08.07.2014
comment
этот код повторяется с уменьшением в обратном направлении, а затем с увеличением вперед. предположим, что если диапазон = 4, то 4321012343210123... и т. д. вместо 0123432101234.... и т. д. Спасибо! - person SridharKritha; 08.07.2014
comment
Упс, ты прав. Вы должны начать с i=range вместо i=0 - person Chris Bogart; 08.07.2014

Я придумал другое решение, хотя и без всяких хитростей. Вот как бы я решил вашу проблему без абсолютной функции:

range = 7; //can be whatever

reverse = false;

for(i = 0; i < 1000; i++){
  if(i%range != 0){
    if(!reverse){
      std::cout<< i % range;
    }else{
      std::cout<< range - (i % range);
    }
  }
  else{
    if((i/range)%2 == 1){
      reverse = true;
      std::cout<< range;
    }else{
      std::cout<< i % range;
      reverse = false;
    }
  }
}

Это даст вам вывод 01234567654321012345676543210...

Мне потребовалось некоторое время, чтобы сделать это, и я знаю, что это не совсем то, что вы хотели, но просто подумал, что я поделюсь.

Ваше здоровье.

Редактировать: Хотя absolute проще, иногда лучше написать свой собственный код, так как вы можете изменить количество условий. Я сомневаюсь, что мой код более эффективен, но кто знает!

Edit2: забыл изменить реверс на true.

person Millar248    schedule 08.07.2014
comment
Я ценю твой эффект. В коде есть некоторые ошибки... ниже приведен вывод, который я получил для вашего кода - 0123456765432106543217654.....проверьте, что 7 и 0 иногда отсутствуют. Спасибо. - person SridharKritha; 08.07.2014
comment
кажется я исправил :D - person Millar248; 08.07.2014