Автор Тема: Очень простой цикл  (Прочитано 56091 раз)

alexus

  • Гость
Re: Очень простой цикл
« Ответ #15 : Май 25, 2012, 07:48:39 pm »
Что будет, если второй ноль окажется вне строки?
Жадность фраера сгубила )))
К сожалению, на таких ошибках ловят... Если второй проверяемый символ окажется "за границей", то возникает исключение, которое уже перехвачено... в стеке... исключений. Но такой код не пишется первоклашками, а теми, кем пишется, не решаются частные задачи...

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #16 : Май 25, 2012, 07:55:43 pm »
Что будет, если второй ноль окажется вне строки?
Жадность фраера сгубила )))
К сожалению, на таких ошибках ловят... Если второй проверяемый символ окажется "за границей", то возникает исключение, которое уже перехвачено... в стеке... исключений. Но такой код не пишется первоклашками, а теми, кем пишется, не решаются частные задачи...
   :( беда в том, что пишется- по крайней мере  делаются попытки... - а некоторые умудряются писать нечто  подобное и на контрольных работах... да что там, я страдал на первом курсе такой болезнью... все хотел "оптимальности" - толком не понимая даже что это такое...

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Очень простой цикл
« Ответ #17 : Май 25, 2012, 10:08:23 pm »
Поиск подпоследовательности из 2 символов:

public static int Search (int[] a, int N, int firstSymbol, int secondSymbol)
{
    int result = -1;
    if (N >= 2)
    {
        int n = 0;
        do
        {
            while ((n < N - 1) && !(a[n] == firstSymbol))
            {
                n++;
            }
            n++;
        }
        while ((n < N) && !(a[n] == secondSymbol));
        if (n < N)
        {
            result = n - 1;
        }
    }
    return result;
}

Поиск подпоследовательности из 3 символов:

public static int Search (int[] a, int N, int firstSymbol, int secondSymbol, int thirdSymbol)
{
    int result = -1;
    if (N >= 3)
    {
        int n = 0;
        do
        {
            do
            {
                while ((n < N - 2) && !(a[n] == firstSymbol))
                {
                    n++;
                }
                n++;
            }
            while ((n < N - 1) && !(a[n] == secondSymbol));
            n++;
        }
        while ((n < N) && !(a[n] == thirdSymbol));
        if (n < N)
        {
            result = n - 2;
        }
    }
    return result;
}

Аналогично для 4, 5 и т. д. символов.

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #18 : Май 26, 2012, 02:16:03 am »
Плохо.
В случае поиска в массиве надо начинать проверку со второго символа (с конца). Если он не 0, то можно продвинуться сразу на 2. (поиск 00)

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #19 : Май 26, 2012, 02:28:27 am »
К сожалению, на таких ошибках ловят... Если второй проверяемый символ окажется "за границей", то возникает исключение, которое уже перехвачено... в стеке... исключений. Но такой код не пишется первоклашками, а теми, кем пишется, не решаются частные задачи...
Так я первоклашка-двоечник )
Это же просто цикл, зачем в него проверку предусловий, очевидно, что такие действия производятся до входа в цикл, на то они и предусловия, и если мы до него дошли, значит там есть что искать.

alexus

  • Гость
Re: Очень простой цикл
« Ответ #20 : Май 26, 2012, 05:23:30 am »
К сожалению, на таких ошибках ловят... Если второй проверяемый символ окажется "за границей", то возникает исключение, которое уже перехвачено... в стеке... исключений. Но такой код не пишется первоклашками, а теми, кем пишется, не решаются частные задачи...
Так я первоклашка-двоечник )
Нет, нет... речь не о Вас, а о том, что на таком уровне (перехват PAGE_FAULT и т.п.) работают профи, труд которых оплачивается из специальных фондов... не менее специальных служб...
В своё время попадалась интересная работа израильтян, где описывались некоторые принципы/методы... например, там говорилось о том, что не надо трогать основной код, но надо фильтровать все исключения... Метод прост и эффективен и не требует внедрения внутрь нулевого кольца...

Илья Ермаков

  • Sr. Member
  • ****
  • Сообщений: 493
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #21 : Май 26, 2012, 06:32:45 am »
Так я первоклашка-двоечник )
Это же просто цикл, зачем в него проверку предусловий, очевидно, что такие действия производятся до входа в цикл, на то они и предусловия, и если мы до него дошли, значит там есть что искать.
Хорошо составленный цикл с условием, как правило, расчитан на выполнение [0..+inf) раз.
Если мы смотрим на программу и видим, что цикл в ней выполняется не менее 1 раза, а сверху навешано условие, чтобы "отсечь" ситуацию 0 раз, то, как правило, можно и нужно преобразовать цикл так, чтобы он был "сам себе условие" на все случаи.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #22 : Май 26, 2012, 08:41:50 am »
Хорошо составленный цикл с условием, как правило, расчитан на выполнение [0..+inf) раз.
Если мы смотрим на программу и видим, что цикл в ней выполняется не менее 1 раза, а сверху навешано условие, чтобы "отсечь" ситуацию 0 раз, то, как правило, можно и нужно преобразовать цикл так, чтобы он был "сам себе условие" на все случаи.
Илья, с методической стороны это, несомненно, верно, и об этом, тоже несомненно, нужно всегда помнить и переходить к следующему шагу оптимизации цикла только после исчерпания возможности преобразования условий вхождения.
С практической - ситуации могут быть разные. Если перед каждой итерацией для проверки истинности условия мы делаем скрытый паразитический декремент ([i-1]), потому, что вошли в цикл не с 0-го а с 1-го индекса, и поэтому вынуждены откатываться назад для проверки, то, по крайней мере для меня, лучше проверить перед циклом, чтобы не накапливать паразитические инструкции.
« Последнее редактирование: Май 26, 2012, 08:43:53 am от Kemet »

Илья Ермаков

  • Sr. Member
  • ****
  • Сообщений: 493
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #23 : Май 26, 2012, 12:31:51 pm »
Я бы тогда просто завёл две переменных, i0, i1...
i0 := 0; i1 := 1

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Очень простой цикл
« Ответ #24 : Май 26, 2012, 01:53:32 pm »
Если мы смотрим на программу и видим, что цикл в ней выполняется не менее 1 раза, а сверху навешано условие, чтобы "отсечь" ситуацию 0 раз, то, как правило, можно и нужно преобразовать цикл так, чтобы он был "сам себе условие" на все случаи.
Ты предлагаешь отказаться от цикла REPEAT-UNTIL. Зачем?

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #25 : Май 27, 2012, 06:19:19 am »
Нет, нет... речь не о Вас,
Как раз обо мне, видимо пора в детский сад или на пенсию, я позволил сбить себя с толку, потому что правильным (для меня) являлся первый вариант, так как на очередном шаге оптимизации я вынес выражение n-1 из цикла, вычислив его один раз.

Илья Ермаков

  • Sr. Member
  • ****
  • Сообщений: 493
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #26 : Май 27, 2012, 08:02:05 am »
Если мы смотрим на программу и видим, что цикл в ней выполняется не менее 1 раза, а сверху навешано условие, чтобы "отсечь" ситуацию 0 раз, то, как правило, можно и нужно преобразовать цикл так, чтобы он был "сам себе условие" на все случаи.
Ты предлагаешь отказаться от цикла REPEAT-UNTIL. Зачем?
Во-первых, у меня "а сверху навешано условие...".
Т.е. если ситуация объективно позволяет REPEAT-UNTIL, то почему нет. А если уже после постановки охраны в IF стало возможным - то нафиг нужно IF + REPEAT вместо WHILE.

По поводу REPEAT - реально только в единственных случаях с ним сталкиваюсь - где идут попытки чего-то сделать до тех пор, пока работа не исчерпается. Пытаться послать в неблокирующий поток, пока длина оставшихся не будет 0, и т.п.

Valery Solovey

  • Hero Member
  • *****
  • Сообщений: 509
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #27 : Май 27, 2012, 08:11:36 pm »
cur := findNext();
prev := cur;
WHILE (cur < len) & (cur - prev # 1) DO
   prev := cur;
   cur := findNext()
END;
IF cur < len THEN use(prev) END

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #28 : Май 28, 2012, 05:50:33 am »
на хацкеле что ли привести вариант:
xs = [1, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1]

find_zeroes   []    = error "Empty list!"
find_zeroes (y:ys)  = find y ys 0
  where
    find 0 (0:zs) n = n
    find _ (z:zs) n = find z zs (n+1)
    find _   []   _ = error "Not found!"
Ваще наверное правильнее было бы оформить в виде связки map-fold-zip, но лень...
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

ilovb

  • Hero Member
  • *****
  • Сообщений: 2538
  • just another nazi test
    • Просмотр профиля
    • Oberon systems
Re: Очень простой цикл
« Ответ #29 : Май 29, 2012, 11:30:22 am »
1С (если нигде не накололся)

Процедура КнопкаВыполнитьНажатие(Кнопка)
   
   Массив = Новый Массив;
   Массив.Добавить(1);
   Массив.Добавить(0);
   Массив.Добавить(1);
   Массив.Добавить(0);
   Массив.Добавить(1);
   Массив.Добавить(0);
   Массив.Добавить(0);
   
   Граница = Массив.ВГраница();
   ТекущийИндекс = 0;
   
   Пока ТекущийИндекс < Граница Цикл
      
      СледующийИндекс = ТекущийИндекс + 1;
      
      Если Массив[ТекущийИндекс] = 0 Тогда
         Если Массив[СледующийИндекс] = 0 Тогда
            Граница = 0; // нашли
         Иначе
            ТекущийИндекс = СледующийИндекс + 1;
         КонецЕсли;
      Иначе
         ТекущийИндекс = СледующийИндекс;
      КонецЕсли;
      
   КонецЦикла;
   
   Если Граница = 0 Тогда
      Сообщить(ТекущийИндекс);
   Иначе
      Сообщить("Хрен");
   КонецЕсли;
   
КонецПроцедуры