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

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Очень простой цикл
« : Май 25, 2012, 03:02:45 pm »
Раз уж речь пошла про циклы... :) Дана последовательность. Найти позицию первого из двух последовательно идущих нулевых элементов. Кто какой цикл считает самым правильным?
1 0 1 1 0 1 0 1 0 0 ...
---------------^

P.S. 2Илья: твой вариант интересен как референсный от школы научного составления циклов.

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #1 : Май 25, 2012, 03:37:31 pm »
Раз уж речь пошла про циклы... :) Дана последовательность. Найти позицию первого из двух последовательно идущих нулевых элементов. Кто какой цикл считает самым правильным?
1 0 1 1 0 1 0 1 0 0 ...
---------------^

P.S. 2Илья: твой вариант интересен как референсный от школы научного составления циклов.
Корявое задание... но лично я за самый простой и наглядный... пусть 2 нуля являются терминальными членами, и получение осуществляется с помощью функции getel() и минимальное число элементов  в последовательности >=2, тогда (конечные автоматы не трогаем)
st1:=getel(); st2:=getel(); ind:=0;
WHILE  ~((st1=0) & (st2=0)) DO
INC(ind);  st1:=st2; st2:=getel();
END;
где то так....

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #2 : Май 25, 2012, 03:40:49 pm »
Условия слишком нечеткие. Одно дело массив, когда можно заглядывать вперед, другое дело, скажем, ленивая последовательность.
Что значит "правильным". Лишнее сравнение в случае массива - это правильно?

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #3 : Май 25, 2012, 03:46:43 pm »
Условия слишком нечеткие. Одно дело массив, когда можно заглядывать вперед, другое дело, скажем, ленивая последовательность.
Что значит "правильным". Лишнее сравнение в случае массива - это правильно?

Заглядывать вперед можно (но не за второй 0). "Правильным" - с поправкой на ваши личные пристрастия. Для кого-то это будет максимально формальная запись (классический конечный автомат в пределе), для кого-то максимально короткая и т.д.

Илья Ермаков

  • Sr. Member
  • ****
  • Сообщений: 493
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #4 : Май 25, 2012, 03:47:36 pm »
Действительно, может быть много вариантов... Но если начинать с самого простого, с массивом, без выборки во вспом. переменные, я бы строил так:
i := 1;
WHILE (i < n) & ~((mas[i-1] = 0) & (mas[i] = 0)) DO
INC(i)
END;
IF i < n THEN
i-1 - искомый
ELSE
не найден
END
Цикл работает с последовательностью любой длины.

Если не массив, а поток, то вариант Dizera...

--- кстати, про КА я тоже сразу подумал, если бы задачка была чуть сложнее, уже стоило бы строить КА...
« Последнее редактирование: Май 25, 2012, 03:49:11 pm от Илья Ермаков »

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #5 : Май 25, 2012, 03:52:51 pm »
Действительно, может быть много вариантов... Но если начинать с самого простого, с массивом, без выборки во вспом. переменные, я бы строил так:

Ага. Т.е., в принципе тебя и Дизера не коробит "двойная проверка" одних и тех же элементов? И постройки КА такая задачка не достойна?

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #6 : Май 25, 2012, 03:52:58 pm »
да , можно и так... но меня смутили пробельные символы между цифрами.. и я не стал напрягаться...

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #7 : Май 25, 2012, 03:55:04 pm »
Действительно, может быть много вариантов... Но если начинать с самого простого, с массивом, без выборки во вспом. переменные, я бы строил так:

Ага. Т.е., в принципе тебя и Дизера не коробит "двойная проверка" одних и тех же элементов? И постройки КА такая задачка не достойна?
НЕТ - я же сказал, что за наглядность.... а КА не стал строить (а так же заниматься "выкрутасами") по причине темы -"Очень простой цикл".и кроме того если автор, темы коряво ее подает не фиг вообще напрягаться..

vlad

  • Hero Member
  • *****
  • Сообщений: 1391
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #8 : Май 25, 2012, 04:09:08 pm »
и кроме того если автор, темы коряво ее подает не фиг вообще напрягаться..

Вот оригинальные данные: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683187(v=vs.85).aspx
Оригинальная задача: сложить полученные строки в массив.

Сначала у меня была идея, собственно, найти два нуля (конец), а потом воспользоваться библиотечной tokenize (указав нули как разделители). Да, и я тоже думал о примерно таких циклах как вы с Ильей привели. Но мне такой цикл показался слишком страшным только для того, чтобы найти конец. Поэтому я в итоге написал так:
wchar_t* env = ::GetEnvironmentStringsW();
...
wchar_t* next;
while ((next = ::wcschr(env, '\x0')) > env)
{
    result.push_back(std::wstring(env, next));
    env = next + 1;
}

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #9 : Май 25, 2012, 04:23:32 pm »
Понял.. 2 Vlad- мне не нравится ваше решение... просто по тому, что оно
1. Не является наглядным
2. Низкоуровневое
ИМХО
1. мое нагляднее (отражает 1 в 1 высокоуровневый алгоритм)
2. легко РЕАЛИЗУЕТСЯ на ЛЮБОМ императивном ЯП
3. знаний собственно ЯП (и подлежащих моделей) - не требуется.
Но  разумеется если ТРЕБУЕТСЯ производительность, то его нужно модифицировать в соответствии с вашими замечаниями...

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #10 : Май 25, 2012, 06:03:59 pm »
В этой задаче, при решении на Обероне, я предпочту раскрутить одну итерацию, как-то так
входные данные
n # 0, result = -1 (индексы начинаются с 0), i = - 1
WHILE ( r < 0 ) & (  i < n  ) DO
    INC (i);
    IF Arr[i] = 0 THEN
        INC(i);
        IF Arr[i] = 0 THEN r := i; DEC(r) END;
    END;
END;

alexus

  • Гость
Re: Очень простой цикл
« Ответ #11 : Май 25, 2012, 06:37:13 pm »
В этой задаче, при решении на Обероне, я предпочту раскрутить одну итерацию, как-то так
входные данные
n # 0, result = -1 (индексы начинаются с 0), i = - 1
WHILE ( r < 0 ) & (  i < n  ) DO
    INC (i);
    IF Arr[i] = 0 THEN
        INC(i);
        IF Arr[i] = 0 THEN r := i; DEC(r) END;
    END;
END;
Что будет, если второй ноль окажется вне строки?

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #12 : Май 25, 2012, 07:05:53 pm »
Что будет, если второй ноль окажется вне строки?
Жадность фраера сгубила )))
Изначально у меня было 2 условных INC, я одним пожадничал, свернул условия и удалил один инкремент, а второй вынес в начало итерации, а условие цикла не поправил, в результате получилась лишняя итерация
WHILE ( r < 0 ) & (  i < n-1 ) DO
    INC (i);
    IF Arr[i] = 0 THEN
        INC(i);
        IF Arr[i] = 0 THEN r := i; DEC(r) END;
    END;
END;

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #13 : Май 25, 2012, 07:12:53 pm »
 2 Kemet Ну и как стоит ваша "развертка" ошибок?  ;)

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #14 : Май 25, 2012, 07:47:55 pm »
2 Kemet Ну и как стоит ваша "развертка" ошибок?  ;)
Да, в принципе, ошибка дурацкая, из-за спешки и расслабухи.
Но раскрутка цикла в данном примере дает существенный профит