Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.06.13;
Скачать: CL | DM;

Вниз

Сколько 1-ых битов в байте? :)   Найти похожие ветки 

 
Соловьев ©   (2004-05-27 09:35) [0]

Форумчане, предлагаю конкурс, кто предложит самый оптимальный способ подсчета сабжа. Надо написать функцию на вход которой подается байт, и надо получить на выходе количество 1-ых битов. Это я вчера проходил тест на фирму - "МаксБилл". Надо было использовать С. мой вариант вышел такой, что не налазит ни накакие ворота :)

char cnt_bit(char in)
{
char result=0, temp=in;
while( temp ){
 if( 255 == (254|temp) )result++;  
 temp--;
}
return result;
}

Это как из Харькова ехать в Москву через Владивосток. Как оказалось решение очень интересное и самое главное очень простое :)
кто решит? можно и на Паскале. Главное быстродействие. Удачи


 
Anatoly Podgoretsky ©   (2004-05-27 09:44) [1]

Критерий оптимальности какой?


 
Соловьев ©   (2004-05-27 09:44) [2]

Быстродействие


 
Ega23 ©   (2004-05-27 09:45) [3]

1-ых - это "Первых" или "Имеющих значение 1"?


 
Anatoly Podgoretsky ©   (2004-05-27 09:47) [4]

Тогда по таблице из 2^SizeOf(Byte) элементов


 
Соловьев ©   (2004-05-27 09:47) [5]


> [3] Ega23 ©   (27.05.04 09:45)

Функция должна выдать - сколько еденичных битов в байте.


 
Соловьев ©   (2004-05-27 09:48) [6]


> [4] Anatoly Podgoretsky ©   (27.05.04 09:47)

подробнее можно?


 
Danilka ©   (2004-05-27 09:48) [7]

Дык, вроде было что-то похожее на прошлой неделе в основной, или нет?

[3] Ega23 ©   (27.05.04 09:45)
Ка я понял, если записать значение в двоичном виде будут нолики и единички. подсчитать скока единичек.


 
jack128 ©   (2004-05-27 09:49) [8]

Была тут ветка про красивый код, вот оттуда

[7] Aldor ©   (18.05.04 21:34)
Из красивого: функция возвращает количество бит в двоичной записи числа

int BitCount(int num)
{
for (int count = 0; num; count++)
  num &= num - 1  
}


 
Anatoly Podgoretsky ©   (2004-05-27 09:49) [9]

Да еще в этом случае и функция не нудна, дополнительное повышение быстродействия, выгдяит так Count := BitsTbl[Byte];


 
jack128 ©   (2004-05-27 09:50) [10]

только return count забыли


 
Соловьев ©   (2004-05-27 09:50) [11]


>  [8] jack128 ©   (27.05.04 09:49)

нет, это не будет самым быстрым


 
Соловьев ©   (2004-05-27 09:51) [12]


> [9] Anatoly Podgoretsky ©   (27.05.04 09:49)

:)
правильно
А что в таблице?


 
Anatoly Podgoretsky ©   (2004-05-27 09:57) [13]

Соловьев ©   (27.05.04 09:51) [12]
А в таблице прописано количество еддиниц для каждого значения байта, в случае 8 битных байт это числа от 9 до 8. Таблица описывается в виде константного массива

const
  BitsTbl: array[Byte] of byte = (значения);


 
Соловьев ©   (2004-05-27 09:59) [14]


> [13] Anatoly Podgoretsky ©   (27.05.04 09:57)

Правильно.


 
Ваххабит   (2004-05-27 10:08) [15]

Отряд из восьми ваххабитов = один ваххобайт.


 
Vlad Oshin ©   (2004-05-27 10:15) [16]

а 0-1 это сексуальная ориентация членов отряда


 
MBo ©   (2004-05-27 10:15) [17]


function Count1Bits(b:byte):byte;
asm
 mov edx,eax
 and eax,$55
 shr edx,1
 and edx,$55
 add eax,edx
 mov edx,eax
 and eax,$33
 shr edx,2
 and edx,$33
 add eax,edx
 mov edx,eax
 and eax,$F
 shr edx,4
 and edx,$F
 add eax,edx
end;


 
MBo ©   (2004-05-27 10:17) [18]

Паскальный бестабличный аналог :

b:=(b and $55)+((b shr 1) and $55);
b:=(b and $33)+((b shr 2) and $33);
Result:=(b and $F)+((b shr 4) and $F);


 
WondeRu ©   (2004-05-27 10:20) [19]

bb1 - твой байт

 xor edx,edx
 mov al, bb1
 mov ecx,8
loop1:
 bt al,cl
 jnc m1
 inc edx
m1:
 loop loop1

edx - количество 1-х бит


 
Соловьев ©   (2004-05-27 10:20) [20]


> [17] MBo ©   (27.05.04 10:15)


> [18] MBo ©   (27.05.04 10:17)

На сколько я знаю - выбать значение из ячейки памяти все-таки быстрее будет, чем суммирование, а насчет асма не знаю, может и самый быстрый способ


 
jack128 ©   (2004-05-27 10:28) [21]


> нет, это не будет самым быстрым
но затоо красиво :-)

а самый быстрый уже предложили..


 
Bless ©   (2004-05-27 11:46) [22]

MBo ©[18]>

Пусть меня покрасят, если я понял, как это работает! Не объяснишь логику? В смысле, как это в голову пришло, как рассуждал?


 
Bless ©   (2004-05-27 11:55) [23]

to Mbo>
Хотел посмотреть твою анкету. Не найдена. Так и было задумано или регистрация пропала?


 
MBo ©   (2004-05-27 12:03) [24]

>Соловьев
Да, конечно, табличный способ намного быстрее всех других за счет траты памяти. Приведенный код не имеет особого смысла для байта, но вот его модификация для 32-х или 64-х разрядных чисел совсем неплоха, поскольку имеет алг. сложность O(logN), а не O(N), которая будет, например, у алгоритма типа
for i:=0 to N-1 do begin
 if Odd(b) then Inc(ButCount);
 b:=b shr 1;
end;


 
Соловьев ©   (2004-05-27 12:07) [25]


> [24] MBo ©   (27.05.04 12:03)

как раз требуется скорость - память не важна


 
Anatoly Podgoretsky ©   (2004-05-27 12:16) [26]

Модифицируется обращением к отдельным байтам и суммированием результатов.


 
Mystic ©   (2004-05-27 12:20) [27]

Классику надо знать ;)
http://russian.joelonsoftware.com/Articles/Interviewing.html

3. Посчитать все ненулевые биты в байте.

Третья задача показывает, насколько хорошо они учили побитовые операторы в Си... но это уже навык, а не способность, и тут им можно помочь. Интересно посмотреть, как они пишут программу, пересчитывающую все биты в байте, а потом попросить сделать это гораздо, гораздо быстрее. Сообразительный кандидат создаст поисковую таблицу (там ведь всего 256 значений), заполняемую только один раз. С хорошим кандидатом можно даже завести интересную беседу о компромиссах между скоростью выполнения и требуемой памятью. Поднажмите. Скажите, что не хотите тратить время на создание таблицы при инициализации. Очень умные кандидаты могут даже предложить схему кэширования, где биты считаются при первом использовании и сохраняются в таблице, чтобы не пересчитывать их в следующий раз. А самые умные попробуют изобрести способ вычисления значений таблицы, используя для этого некие расширенные методы программирования.


Итого --- не взяли?


 
MBo ©   (2004-05-27 12:34) [28]

>Соловьев
Я все понимаю ;)

>Bless ©   (27.05.04 11:46) [22]
Идея не моя. Числа $55,$33,$F предсталяют собой битовые маски для выделения четных битов, групп по 2 и по 4 бита соответственно
$55=01010101B
$33=00110011B
На первом шаге мы выделяем четные и нечетные биты, второе число сдвигаем и складываем. При этом из числа, например, 00001100B получатся
00000100 и 00000100 (старший бит каждого слагаемого всегда нулевой). Сложив их, получим 00001000B. Следующий шаг требует сдвига на 2, пары битов выделяются, получим 0 и 00000010, и сумма 00000010. Последний шаг для взятого числа (старший ниббл-полубайт нулевой) ничего не изменит, так и останется 00000010B=2


 
Соловьев ©   (2004-05-27 12:44) [29]


> Итого --- не взяли?

это мне?


 
вразлет ©   (2004-05-27 12:54) [30]

Сколько 1-ых битов в байте?

в любом байте первый бит всегда один)


 
Sergp ©   (2004-05-27 12:55) [31]


> в любом байте первый бит всегда один)


А если учесть что может быть первый сзади и первый спереди, то два.. :-))


 
Bless ©   (2004-05-27 12:58) [32]

MBo © [28]>

Дык, я ж не о том спросил. Что каждая строчка кода делает, я и сам понимаю. Но каким образом эти действия приводят к желаемому результату, я никак не могу понять.

Для меня не очевидно, что эта последовательность действий для любого байта вернет правильный результат. Но ведь вернет же!

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


 
Alx2 ©   (2004-05-27 13:02) [33]

>Bless ©   (27.05.04 12:58) [32]
На первом шаге мы резервируем четыре счетчика - столько пар бит в байте. В итоге после первой операции в каждой паре бит будет храниться 0, 1, либо 10 (двоичная двойка), что будет означать сумму соседних бит.
На втором шаге получим два счетчика - четверки бит. Каждая четверка будет содержать сумму соседних двух счетчиков (двубитных) предыдущего шага.
Наконец, на третьем шаге, складываем значения двух четырехбитных счетчиков и получаем итоговую сумму бит.


 
Anatoly Podgoretsky ©   (2004-05-27 13:02) [34]

Bless ©   (27.05.04 12:58) [32]
А ты поиграйся на бумаге с разными значениями, чтобы визуально видеть, что происходит при этом.


 
MBo ©   (2004-05-27 13:11) [35]

Вот еще из занятных трюков (меняет n-й и m-й биты числа)

function BitSwap(i:Integer; n,m:byte):Integer;
begin
if Odd((i shr n) xor (i shr m)) then //биты различны
 Result:=i xor ((1 shl m) xor (1 shl m))
else
 Result:=i;
end;


 
Alx2 ©   (2004-05-27 13:14) [36]

>MBo ©   (27.05.04 13:11) [35]
Опечятка:
Result:=i xor ((1 shl m) xor (1 shl n))

:)


 
MBo ©   (2004-05-27 13:21) [37]

>Alx2 ©   (27.05.04 13:14) [36] Опечятка:
Угу ;(


 
Думкин ©   (2004-05-27 13:23) [38]

> Bless ©   (27.05.04 12:58) [32]

В свое время я благоговел глядя на картину "Трудная задача". Всему свое время.


 
MBo ©   (2004-05-27 13:31) [39]

>Думкин ©   (27.05.04 13:23) [38]
Да ладно тебе, код действительно нетривиальный. Самому такое придумать - крыша может поехать ;)
(анонс - в завтрашних задачках будет о едущей крыше ;)))


 
Bless ©   (2004-05-27 13:38) [40]

MBo ©  (27.05.04 13:31) [39]
> в завтрашних задачках будет о едущей крыше ;)))
У меня еще от бегущей вокруг строя собачки крыша едет :) До сих пор перед сном решаю. Кстати, ее решил кто-то в той ветке или нет (только ответ не говори) ?


 
MBo ©   (2004-05-27 13:42) [41]

>Bless
Да, решили.


 
MBo ©   (2004-05-27 13:50) [42]

>Bless ©
Если ты решаешь 1б, то учти, что выражение довольно сложное - так и должно быть


 
вразлет ©   (2004-05-27 13:52) [43]

MBo ©
Почему же нетривиальный? Метод деления пополам. Каждый из нас его использует при локализации ошибок в програме


 
вразлет ©   (2004-05-27 13:52) [44]

мм


 
Bless ©   (2004-05-27 14:02) [45]

Alx2 [33]>

Спасибо за объяснение. Дошло :)


 
Mystic ©   (2004-05-27 14:23) [46]

>> Итого --- не взяли?
> это мне?


Ну интересно же...


 
Соловьев ©   (2004-05-27 14:33) [47]

прочитал статью - они вели себя как там написано, а там написано что если сомневаешся то не бери. А они сказали , что на 95% я им подхожу, а на 5% сомневаются :)

Ксати, может и расстраиваться не стоит? Как Вам "МаксБилл" - кто нибудь хорошее или плохое сказать может?


 
MBo ©   (2004-05-27 14:38) [48]

>Соловьев
А много ли было задачек и как остальные решил?
Эту, конечно, стоило сделать, но понятно, что не всегда можно сразу сообразить, бывает, зациклишься на неверном варианте (или не не том, который от тебя ждут :)).


 
Соловьев ©   (2004-05-27 14:55) [49]


> А много ли было задачек и как остальные решил?

Были вопросы по SQL - решил половину.
Оракл не знаю, но решил 10% :)
Delphi - тоже половину
RDBMS тоже не знаю, но решил 40 % :)


 
Mystic ©   (2004-05-27 15:15) [50]


> Ксати, может и расстраиваться не стоит? Как Вам "МаксБилл"
> - кто нибудь хорошее или плохое сказать может?


Я давно там собеседовался... Тогда еще им эта статья была неизвестной ;) Мне объяснили, что за фирма, сказали, что им нужен программист с глубинными знаниями VCL. Я сказал, что этими знаниями обладаю. Потом спросили знали я SQL. Я ответил, что знаю. Сказали, что они специализируюсят на Oracle и MS SQL. Я сказал, что работал с MS SQL. Спросили --- могу ли я писать компоненты. Я сказал, что могу. Потом нехорошо маякнули, что поскольку я буду не успевать выполнять их задания во время, то согласен ли я оставаться после конца рабочего дня? Последнее их слово было ждите. Жду до сегодняшнего дня ;)


 
Соловьев ©   (2004-05-27 15:19) [51]


> [50] Mystic ©   (27.05.04 15:15)

вот и меня смущает, что до реального программирования дело не доходило, а они уже сразу о контракте начали вести разговор...


 
Соловьев ©   (2004-05-27 15:20) [52]


> Потом нехорошо маякнули, что поскольку я буду не успевать
> выполнять их задания во время, то согласен ли я оставаться
> после конца рабочего дня?

да :)
говорят у нас есть - овертайм. Я говорю и как часто? сказали, если курить меньше будешь, то его нет. а я не курю:) в общем мне не грозит работа по выходным :))))


 
Mystic ©   (2004-05-27 15:55) [53]

Просто это было несколько лет назад. Насколько до меня доходили слухи, то, в отличие, например, от МИИТ, estimate-лист (работы, время выполнения) там никак не согласовывается с тобой лично, и строится с таким расчетом, чтобы ты его сделать не успел.

Я бы порекомендовал попытаться устроиться в МИИТ (там недавно был набор).


 
Соловьев ©   (2004-05-27 15:59) [54]


> бы порекомендовал попытаться устроиться в МИИТ (там недавно
> был набор).

МИИТ? МИИК может?
У меня там друг работает, классная кантора, но им надо знание Оракла и Явы, а этого увы не знаю, хочу, но не знаю. Буду учить...


 
Mystic ©   (2004-05-27 16:10) [55]

МИИТ = МИИК. Я их всегда путаю... Там, кстати, недавно были вакансии на С++. Можешь еще сюда обратиться:

http://via.com.ua/jobs/jobs.aspx


 
Соловьев ©   (2004-05-27 16:37) [56]


> http://via.com.ua/jobs/jobs.aspx

У меня ни одна кодировка не подходит... В какой их сайт?


 
app ©   (2004-05-27 16:48) [57]

Мыжики считаем биты в байте или заводим отдельную ветку


 
Соловьев ©   (2004-05-27 16:55) [58]


> [57] app ©   (27.05.04 16:48)

закрываем тему :)
разобрался.



Страницы: 1 2 вся ветка

Текущий архив: 2004.06.13;
Скачать: CL | DM;

Наверх




Память: 0.62 MB
Время: 0.024 c
14-1085115969
MBo
2004-05-21 09:06
2004.06.13
Пятница... Опять задачки, туды их в качель ;)


6-1082617656
TOleg
2004-04-22 11:07
2004.06.13
Что это за ошибка - "500 Invalid Port Command"


1-1084984795
ceval
2004-05-19 20:39
2004.06.13
Подскажите как сделать чтобы в ComboBox се отбражалось одн


14-1085585986
Drakon
2004-05-26 19:39
2004.06.13
GMail


3-1084988072
Dmitry Vyacheslavovich
2004-05-19 21:34
2004.06.13
Конфигурация InstallShield для работы с DB