цикл for для увеличения / уменьшения диапазона на основе знака шага - PullRequest
0 голосов
/ 01 марта 2019

Как бы я изменил этот цикл for таким образом, чтобы он учитывал положительные значения Step, но отсчитывал отрицательные значения Step?

Для Step = 2 ожидаемый результат равен2 4 6 8 10

Для Step =- 2 ожидаемый результат составляет 10 8 6 4 2

// assume these 3 come from user input
int Lower = 2;
int Upper = 10;
int Step = 2;

for ( int i = Lower; i <= Upper; i += Step )
{
    Console.Write(i + " ");
}

Ответы [ 6 ]

0 голосов
/ 01 марта 2019
for(int i=Step>0?Lower:Upper; Step>0? i<=Upper: i>= Lower; i+=Step)
{
    Console.Write(i + " ");
}

@ john Все, что нужно для обновления условий цикла.

0 голосов
/ 01 марта 2019

Просто соблюдайте принцип KISS .

Вы можете просто поместить логику в инициализатор и выполнить условие for :

public static void ForLoopWithDirectionBasedOnStep(int minValue, int maxValue, int step)
{
    // Avoid obvious hang
    if ( step == 0 )
        throw new ArgumentException("step cannot be zero");

    //  ( initialiser                           ; condition                     ; iterator  )
    for ( int i = step > 0 ? minValue : maxValue; minValue <= i && i <= maxValue; i += step )
        Console.Write(i + " ");
}

так:

  • ForLoopWithDirectionBasedOnStep(minValue: 2, maxValue: 10, step: 2) возвращает:

    2 4 6 8 10
    
  • ForLoopWithDirectionBasedOnStep(minValue: 2, maxValue: 10, step: -2) возвращает:

    10 8 6 4 2
    

по желанию.


Инициализатор устанавливает начальное значение

int i = step > 0 ? minValue : maxValue;

, используя условный оператор и эквивалентно

int i;
if ( step > 0 )
    i = minValue;
else
    i = maxValue;

Условие

minValue <= i && i <= maxValue

просто проверяет, что переменная цикла находится в диапазоне [minValue, maxValue].


Примечаниечто неправильные входные данные обрабатываются автоматически, потому что (выделение мое):

Раздел условия, если он присутствует, должен быть логическим выражением. Это выражение вычисляется перед каждой итерацией цикла.

, поэтому что-то вроде ForLoopWithDirectionBasedOnStep(minValue: 10, maxValue: 0, step: -2), которое будет отсчитываться от 0 до 10, ничего не печатает, потому что, поскольку0 <10, тело оператора <code>for никогда не выполняется.

0 голосов
/ 01 марта 2019

Вы можете сделать два цикла, основываясь на знаке переменной step:

static void Main(string[] args)
    {
      int lower = 2;
      int upper = 10;
      int step = -2;

      if (Math.Sign(step) == 1)
      {
        for (int i = step; i < upper; i += step)
        {
          Console.WriteLine(string.Format("{0}", i));
        }
      }
      else if (Math.Sign(step) == -1)
      {
        for (int i = upper; i >= lower; i += step)
        {
          Console.WriteLine(string.Format("{0}", i));
        }
      }
      Console.ReadLine();
    }
  }
0 голосов
/ 01 марта 2019

Вам необходим шаг предварительной обработки, чтобы изменить сравнение в цикле for, а также его пределы

int Lower = 2;
int Upper = 10;
int Step = -2;
Func<int, bool> comparator = (j) => j <= Upper;


if (Step < 0)
{
    var temp = Lower;
    Lower = Upper;
    Upper = temp;
    comparator = (j) => j >= Upper;
}


for(int i=Lower; comparator(i); i+=Step)
{
    Console.Write(i + " ");
}

DotNetFiddle

0 голосов
/ 01 марта 2019

Вы можете сделать делегат Func, чтобы проверить, является ли шаг отрицательным, и инвертировать условие проверки привязки.

Вот пример:


class Program
{
    public static void Print(int Lower, int Upper, int Step)
    {
        Func<int, bool> checkBounds = (i) => i <= Upper;

        if (Step < 0)
        {
            Swap(ref Lower, ref Upper);
            checkBounds = (i) => i >= Upper;
        }

        for (int i = Lower; checkBounds(i); i += Step)
            Console.Write($"{i} ");
    }

    public static void Swap<T>(ref T a, ref T b)
    {
        T temp = a;
        a = b;
        b = temp;
    }

    static void Main(string[] args)
    {
        // assume these 3 come from user input
        int Lower = 2;
        int Upper = 10;
        int Step = -2;

        Print(Lower, Upper, Step);
    }
}
0 голосов
/ 01 марта 2019

Обратите внимание, что этот код не проверен, но идея состоит в том, чтобы использовать Predicate<T> для цикла и переключать Upper и Lower, если шаг отрицательный

// assume these 3 come from user input
int Lower = 2;
int Upper = 10;
int Step = 2;
if(step < 0){ int temp = Lower; Lower = Upper; Upper = temp;}
Predicate<int> LoopPred = (i =>
{
  if(Step < 0)
    return i >= Upper;
  return i <= Upper;
})


for(int i=Lower; LoopPred(i); i+=Step)
{
    Console.Write(i + “ “);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...