Чистый, эффективный алгоритм для упаковки целых чисел в C ++ - PullRequest
26 голосов
/ 02 апреля 2009
/**
  * Returns a number between kLowerBound and kUpperBound
  * e.g.: Wrap(-1, 0, 4); // Returns 4
  * e.g.: Wrap(5, 0, 4); // Returns 0      
  */
int Wrap(int const kX, int const kLowerBound, int const kUpperBound)
{
    // Suggest an implementation?
}

Ответы [ 13 ]

0 голосов
/ 02 апреля 2009

Ответ, который имеет некоторую симметрию и также делает очевидным, что когда kX находится в диапазоне, он возвращается без изменений.

int Wrap(int const kX, int const kLowerBound, int const kUpperBound)
{
    int range_size = kUpperBound - kLowerBound + 1;

    if (kX < kLowerBound)
        return kX + range_size * ((kLowerBound - kX) / range_size + 1);

    if (kX > kUpperBound)
        return kX - range_size * ((kX - kUpperBound) / range_size + 1);

    return kX;
}
0 голосов
/ 02 апреля 2009

Я бы предложил это решение:

int Wrap(int const kX, int const kLowerBound, int const kUpperBound)
{
    int d = kUpperBound - kLowerBound + 1;
    return kLowerBound + (kX >= 0 ? kX % d : -kX % d ? d - (-kX % d) : 0);
}

Логика if-then-else оператора ?: гарантирует, что оба операнда % неотрицательны.

0 голосов
/ 02 апреля 2009

Для отрицательного kX вы можете добавить:

int temp = kUpperBound - kLowerBound + 1;
while (kX < 0) kX += temp;
return kX%temp + kLowerBound;
...