Это может быть сделано с наихудшим случаем менее 32 операций:
Это может быть сделано с наихудшим случаем менее 32 операций: Проверка на 2 или более бит так же эффективно, как проверка на 1 бит.
Так, например, нет ничего, что мешает вам проверить, для какой группировки его сначала, затем проверяя каждый бит от наименьшего до самого большого в этой группе.
Итак ... если вы проверите 2 бит в то время, когда у вас есть в худшем случае (Nbits / 2) + 1 общее количество проверок. если вы проверите 3 бита за раз, когда у вас есть в худшем случае (Nbits / 3) + 2, проверите общее количество. ...
Оптимальное было бы проверять группы из 4. Для чего потребуется в худшем случае 11 операций вместо вашего 32.
Лучший случай идет от проверки 1 ваших алгоритмов хотя до 2 проверок, если вы используете эту идею группировки. Но эта дополнительная 1 проверка в лучшем случае стоит того, чтобы сэкономить наихудший случай.
Примечание: я пишу это полностью, вместо того, чтобы использовать цикл, потому что он более эффективен таким образом.
int getLowestBitPos(unsigned int value)
{
//Group 1: Bits 0-3
if(value&0xf)
{
if(value&0x1)
return 0;
else if(value&0x2)
return 1;
else if(value&0x4)
return 2;
else
return 3;
}
//Group 2: Bits 4-7
if(value&0xf0)
{
if(value&0x10)
return 4;
else if(value&0x20)
return 5;
else if(value&0x40)
return 6;
else
return 7;
}
//Group 3: Bits 8-11
if(value&0xf00)
{
if(value&0x100)
return 8;
else if(value&0x200)
return 9;
else if(value&0x400)
return 10;
else
return 11;
}
//Group 4: Bits 12-15
if(value&0xf000)
{
if(value&0x1000)
return 12;
else if(value&0x2000)
return 13;
else if(value&0x4000)
return 14;
else
return 15;
}
//Group 5: Bits 16-19
if(value&0xf0000)
{
if(value&0x10000)
return 16;
else if(value&0x20000)
return 17;
else if(value&0x40000)
return 18;
else
return 19;
}
//Group 6: Bits 20-23
if(value&0xf00000)
{
if(value&0x100000)
return 20;
else if(value&0x200000)
return 21;
else if(value&0x400000)
return 22;
else
return 23;
}
//Group 7: Bits 24-27
if(value&0xf000000)
{
if(value&0x1000000)
return 24;
else if(value&0x2000000)
return 25;
else if(value&0x4000000)
return 26;
else
return 27;
}
//Group 8: Bits 28-31
if(value&0xf0000000)
{
if(value&0x10000000)
return 28;
else if(value&0x20000000)
return 29;
else if(value&0x40000000)
return 30;
else
return 31;
}
return -1;
}
Простой рекурсивный чек будет достаточно и будет возвращаться как можно раньше, мы предполагаем, что он не является списком или содержит не-списки, он не пуст
def isEmpty (alist) : try: for a in alist: if not isEmpty (a): return False, за исключением: # мы будем здесь, если alist не является возвратом итератора / списка False return True alist = [] blist = [alist] # [[]] clist = [alist, alist, alist] # [[], [], []] dlist = [blist] # [[[]]] elist = [1, isEmpty, dlist] if isEmpty (alist): print "alist «is empty» if isEmpty (dlist): print «dlist is empty», если не isEmpty (elist): print «elist is not empty»
Вы можете дополнительно улучшить его, чтобы проверить рекурсивный список или нет объектов списка, или может быть пустым dicts и т. д.
def isEmpty (a): return all ([isEmpty (b) для b в a]) if isinstance (a, list) else False
Просто.
Я не думаю, что есть очевидный способ сделать это в Python. Лучше всего было бы использовать рекурсивную функцию, подобную этой:
def empty (li): if li == []: return True else: return all ((isinstance (sli, list ) и empty (sli)) для sli в li)
Обратите внимание, что все
входят только с Python> = 2.5 и что он не будет обрабатывать бесконечно рекурсивные списки (например, a = []; a.append (a)
).
Простой код работает для любого итеративного объекта, а не только из списков:
& gt; & gt; & gt; & gt; def empty (seq): ... try: ... return all (map (empty, seq)) ... кроме TypeError: ... return False ... & gt; & gt; & gt; & gt; empty ([]) True & gt; & gt; & gt; & gt; & gt; empty ([4]) False & gt; & gt; & gt; & gt; empty ([[]]) True & gt; & gt; & gt; & gt; empty ([[], []]) True & gt; & gt; & gt; & gt; & gt; empty ([[], [8]]) False & gt; & gt; & gt; & gt; & gt; empty ([[], (False для _ в диапазоне (0))]) True & gt; & gt; & gt; & gt; & gt; empty ([[], (False для _ в диапазоне (1))]) False & gt; & gt; & gt; & gt; empty ([[], (True для _ в диапазоне (1))]) False
Этот код делает предположение, что все, что может быть повторено, будет содержать другие элементы, и не должно считаться листом в «дереве». Если попытка перебора объекта перестает работать, то это не последовательность и, следовательно, конечно, не пустая последовательность (при этом возвращается False
). Наконец, этот код использует тот факт, что все возвращают True
, если его аргумент является пустой последовательностью.
map
не следует использовать в Python. все (пусто (x) для x в seq)
звучит намного приятнее для меня ;-)
– Jochen Ritzel
20 October 2009 в 12:51
isEmpty ([1])
терпит неудачу, это довольно проблема (на самом деле не очень полезно иметь функцию для проверки пустого списка, если она работает только со списками, которые, как вы знаете, пусты). – Pierre Bourdon 20 October 2009 в 11:14return all (map (isListEmpty, inList)) if isinstance (inList, list) else False
:) – Stephan202 22 October 2009 в 09:45