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

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #90 : Июнь 05, 2012, 04:28:53 pm »
wchar_t бывает 32-битным, причем не на самых экзотических платформах (Мак). Кроме того, даже в случае 16-битного wchar_t - два нуля могут лечь между двумя 32-битными int.

C#:
char - 2 byte
Кстати, а как в винде и шарпе живут с таким недоюникодом? Это же получается UCS-16, который не покрывает весь диапазон юникодовых символов. В нормальных системах и языках обычно для обработки хранят в UCS-32, он же UTF-32, который включает в себя весь юникоддиапазон при фиксированном размере кодирования одного символа.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #91 : Июнь 05, 2012, 04:52:33 pm »
Пардон, ucs-2 и ucs-4 конечно. Вечно путаю где там биты а где байты.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #92 : Июнь 05, 2012, 04:57:07 pm »

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

1. ДА
2. Вот ИМЕННО по этому я и "развонялся" -в  исходной постановке задача ,  бесполезная трата времени... судить вы же ВСЕ  РАВНО будете относительно своей задачи.
3. Я вам ответил- код чуть выше адаптация моего исходного (с учетом ваших уточнений). Скорость -раскрытие условия -drawback - потеря наглядности (но замечу, что это делается без вые... онов аля Сергей и доступно начинающему)
4. Насчет инфо21 - тут несколько проблем проистекающих из идолопоклонничества... как Доцент натягивал, глаз на жопу Николе Питерскому, так и  культисты натягивают на все ЦД (или наоборот?) - глумиться над этим  я устал(временно)...
Но решение Инфо21 ИМХО гораздо понятнее чем ваше..

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #93 : Июнь 05, 2012, 07:04:47 pm »
 :D :D :D господа, не удержался  , глянул в коровник по Владовской ссылке... и что могу сказать... нафиг Прометей, да long live  cowshed! заряд "одреналина"  хоть и не в 3d но бесплатно, господа "мракобесы"  :)

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #94 : Июнь 06, 2012, 05:38:29 am »
В борьбе с рукосуйством и мракобесием Info21 малость обосрался.
Цитата: Info21
"Рукосуи, не понимающие, с чем "едят" ЦД (это про альтернативно удаленных), не въезжают, что конъюнкция отрицаний охран сразу доказывает корректность цикла:
(i >= LEN(a)) OR (oneZero & (a[ i]=0))"
Конъюнкция отрицаний охран, дорогой товарищ, НЕ доказывает корректность цикла. Ни сразу ни потом. Корректность цикла доказывает конъюнкция отрицаний охран & инвариант цикла. Игнорирование последнего весьма характерно для любителей линейного поиска во главе с Info21. Инвариант им на хрен не нужен, я как-то писал об этом на оберонкоре. Само собой, то сообщение было удалено Темиргалеевым.
Я конечно неграмытное быдло, но разве в данном случае
(i >= LEN(a)) OR (oneZero & (a[ i]=0))не есть инвариант цикла?
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #95 : Июнь 06, 2012, 06:45:39 am »
Я конечно неграмытное быдло, но разве в данном случае
(i >= LEN(a)) OR (oneZero & (a[ i]=0))не есть инвариант цикла?
Нет  :)
Формулировать и подсказывать инвариант цикла я не буду. Предлагаю это сделать участникам соревнований. Уже 3 года как.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #96 : Июнь 06, 2012, 07:35:15 am »
Я конечно неграмытное быдло, но разве в данном случае
(i >= LEN(a)) OR (oneZero & (a[ i]=0))не есть инвариант цикла?
Гм. Реально неграмотное быдло. Впрочем, как обычно с утра (хоть зарекайся не писать ничего и к коду себя не подпускать до пяти-шести часов дня).

Естественно хотел сказать, что это отрицание инварианта. Инваринт конечно вот:
~(i >= LEN(a)) OR (oneZero & (a[ i]=0))
Как-то так.

Но конечно могу быть где-то еще не прав, ибо все еще утро :-)
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #97 : Июнь 06, 2012, 07:36:38 am »
Нет  :)
Формулировать и подсказывать инвариант цикла я не буду. Предлагаю это сделать участникам соревнований. Уже 3 года как.
Злой ты... :-)
А вообще, соревнования эти уже начинают напоминать специальную олимпиаду.
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #98 : Июнь 06, 2012, 10:41:02 am »
Кстати, должен присоединиться к DIzer'у и поставить vlad'у жирный минус за безобразность начальной формулировки задачи. У меня оно сразу же отбило желание что-либо делать.
При том, что реальная задача, озвученная позже, вполне хороша. И поиска двух нулей там вообще нет - к массиву добавляются строки, оканчивающиеся 0, до тех пор, пока не встретится строка нулевой длины.

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

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Очень простой цикл
« Ответ #99 : Июнь 06, 2012, 01:06:24 pm »
Кстати, а как в винде и шарпе живут с таким недоюникодом?
Библиотечная процедура читающая текстовый юникодный файл возвращает 4-байтовый int

namespace System.IO
{
   public class StreamReader: TextReader
   {
      //
      // Summary:
      //     Reads the next character from the input stream and advances the character
      //     position by one character.
      //
      // Returns:
      //     The next character from the input stream represented as an System.Int32 object,
      //     or -1 if no more characters are available.
      //
      // Exceptions:
      //   System.IO.IOException:
      //     An I/O error occurs.
      public override int Read ();

Хочешь сужай полученный int в 2-байтовый char, а не хочешь - не сужай (работай врукопашную с массивами int), дело-то хозяйское.

А вообще конечно ни для кого не секрет, что 2-байтовый char (при > 50'000 одном лишь Японском алфавите) это англосаксонские империалистические происки, это даже у Таненбаума в "Архитектура компьютера" написано.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #100 : Июнь 06, 2012, 01:24:07 pm »
Кстати, а как в винде и шарпе живут с таким недоюникодом?
Библиотечная процедура читающая текстовый юникодный файл возвращает 4-байтовый int

namespace System.IO
{
   public class StreamReader: TextReader
   {
      //
      // Summary:
      //     Reads the next character from the input stream and advances the character
      //     position by one character.
      //
      // Returns:
      //     The next character from the input stream represented as an System.Int32 object,
      //     or -1 if no more characters are available.
      //
      // Exceptions:
      //   System.IO.IOException:
      //     An I/O error occurs.
      public override int Read ();

Хочешь сужай полученный int в 2-байтовый char, а не хочешь - не сужай (работай врукопашную с массивами int), дело-то хозяйское.
Ага. То есть можно, но врукопашную. Ну, хоть это радует.

А вообще конечно ни для кого не секрет, что 2-байтовый char (при > 50'000 одном лишь Японском алфавите) это англосаксонские империалистические происки, это даже у Таненбаума в "Архитектура компьютера" написано.
Угу. Это при том, что во всех юниксах и недоюниксах (linux) и совсем не юниксах, а просто нормальных системах, (Haiku/BeOS) 4 байта либо utf8 в качестве альтернативного кактуса. Ну и в других языках этой проблемы тоже нет (по моему, только в жабе есть, хотя там вроде бы перешли на UTF-16 с UCS-2, что с одной стороны черевато, но с другой дает полный охват юникода).

Кстати, заметь - англосаксы уже идут на уступки, раньше то был вообще жестко однобайтовый ASCII. :-)
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #101 : Июнь 06, 2012, 05:40:39 pm »
Кстати, должен присоединиться к DIzer'у и поставить vlad'у жирный минус за безобразность начальной формулировки задачи. У меня оно сразу же отбило желание что-либо делать.

ОК. только напомню что ваша относительно недавно инициированная тема(про сортировку) обладала ровно такими же "достоинствами" как и Влада.

Kemet

  • Hero Member
  • *****
  • Сообщений: 587
    • Просмотр профиля
Re: Очень простой цикл
« Ответ #102 : Июнь 06, 2012, 07:29:49 pm »
Капец, пока меня не было уже успели подраться )))
А что там с ЦД и инвариантами? Я правильно понимаю, что в случае с ЦД однородность не постулируется? Тогда что есть инвариант в ЦД?

DIzer

  • Гость
Re: Очень простой цикл
« Ответ #103 : Июнь 06, 2012, 11:03:13 pm »

А что там с ЦД и инвариантами? Я правильно понимаю, что в случае с ЦД однородность не постулируется? Тогда что есть инвариант в ЦД?
  :) А этот вопрос не к нам = это в коровник, либо к Петру только он ничего не скажет.  :) тихарит инфу, короче...

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

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Очень простой цикл
« Ответ #104 : Июнь 07, 2012, 10:53:20 am »
Померил скорость работы 4 разных алгоритмов.

Поиск 4-байтового нуля:
static long A1 (char* begin)
{
   char* p = begin;
   while (*((int*)p) != 0)
   {
      p++;
   }
   return (long)(p - begin);
}

Два вложенных цикла:
static long A2 (char* begin)
{
   char* p = begin;
   do
   {
      while (*p != 0)
      {
         p++;
      }
      p++;
   }
   while (*p != 0);
   return (long)(p - begin) - 1;
}

Двойная проверка:
static long A3 (char* begin)
{
   char* p = begin;
   while (!((*p == 0) && (*(p+1) == 0)))
   {
      p++;
   }
   return (long)(p - begin);
}

Поиск а-ля чокнутый доктор, но оптимизированный по самые помидоры (авторская чокнутая вспомогательная переменная oneZero оставлена):
static long A4 (char* begin)
{
   char* p = begin;
   bool oneZero = false;
   while (true)
   {
      if (!oneZero)
      {
         oneZero = (*p == 0);
         p++;
      }
      else if (*p != 0)
      {
         oneZero = false;
         p++;
      }
      else
      {
         break;
      }
   }
   return (long)(p - begin) - 1;
}

Измерял десять раз прокручивая по массиву из миллиарда чаров циклически заполненных значениями 0..char.MaxValue

char[] buffer = new char[1000000000];
for (int i = 0; i < buffer.Length; i++)
{
   buffer[ i ] = (char)i;
}
buffer[buffer.Length - 1] = (char)0;
buffer[buffer.Length - 2] = (char)0;

Каждый тест прогнал 3 раза. Из трёх взял лучший результат.

Итого:
A1  3.04 seconds
A2  5.60 seconds
A3  5.60 seconds
A4  6.79 seconds

Win 7, 64 bit, .Net 4.0, i7 2600K.

Прикреплённый архив содержит бинарник плюс исходник (проект на C# для 2010-студии).