Архив рубрики: Python

Python вычисление расстояния Хемминга между двоичными числами

Расстоянием Хемминга d(a,b) между двумя двоичными словами a и b называют число не совпадающих позиций в них. Для строк, количество различающихся позиций для строк с одинаковой длинной. Расстояние Хэмминга уже довольно широко используется для различных задач, таких как поиск близких дубликатов, распознавание образов, классификация документов, исправление ошибок, обнаружения вирусов и т.д.
Рассчитывается расстояние для двоичных чисел как исключающее ИЛИ (XOR) между двумя этими числами сложенное поэлементно. Например:
117 = 0 1 1 1 0 1 0 1 

  17 = 0 0 0 1 0 0 0 1 
   H = 0+1+1+0+0+1+0+0 = 3 — расстояние Хемминга
код на Python
int(reduce(lambda x, y: int(x) + int(y), list(bin(a ^ b)[2:])))
или

str(bin(a^b)).count('1')

Автор: Viktor

Python нахождение числового палиндрома

«А роза упала на лапу Азора» — палиндром, 131 — числовой палиндром.
Решение: число представляю в виде строки, прохожу по циклу от 0 до половины размера строки и сравниваю последовательно симметрично i и -(i +1). Все одинаковые значения добавляются в список и в конце сравниваю размер списка с половиной размера строки. Если равны — то палиндром.
Дебаг:
x = 1234321
for i in xrange(len(str(x)) // 2):    
    if str(x)[i] == str(x)[-(i + 1)]:
        print str(x)[i] 

Привожу в однострочник:
if len([i for i in xrange(len(str(x)) // 2) if str(x)[i] == str(x)[-(i + 1)]]) == len(xrange(len(str(x)) // 2)):
    print 'Палиндром'

Или красивое решение 🙂

def isPalindrom(n):
    «»»
    Check integer for palindrom
    >>> isPalindrom(131)
    True
    >>> isPalindrom(130)
    False
    «»»
    return str(n) == str(n)[::-1]

Автор: Viktor

Линейный поиск

Линейный, последовательный поиск — алгоритм нахождения заданного значения произвольной функции на некотором отрезке. Данный алгоритм является простейшим алгоритмом поиска и в отличие, например, от двоичного поиска, не накладывает никаких ограничений на функцию и имеет простейшую реализацию. Поиск значения функции осуществляется простым сравнением очередного рассматриваемого значения (как правило поиск происходит слева направо, то есть от меньших значений аргумента к большим) и, если значения совпадают (с той или иной точностью), то поиск считается завершённым.
Данный алгоритм приведен здесь, для полноты изложения. Он мало где используется, только если в собственных проектах, которые не накладывают серьезных требований к производительности системы.

Рассматриваем, левую и правую границы отрезка массива, где находится нужный нам элемент. Исследования начинаются с первого элемента отрезка. Если искомое значение не равно значению функции в данной точке, то осуществляется переход к следующей точке. Т.е., в результате каждой проверки область поиска уменьшается на один элемент.

def linearSearch(li, x):
i = 0
length = len(li)
while i li[i]:
i+=1
return i if i

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

def linearSearchVirt(li, x):
i = 0
length = len(li)-1
while x x<> li[i]:
i+=1
return i if i

Вот и весь линейный поиск!)
Но есть более интересный метод -  двоичный поиск, милости просим к изучению.

Автор: Pavel Petropavlov

Сортировка слиянием

Сортировка слиянием (англ. merge sort) — алгоритм сортировки, который упорядочивает списки (или другие структуры данных, доступ к элементам которых можно получать только последовательно, например — потоки) в определённом порядке. Сначала задача разбивается на несколько подзадач меньшего размера. Затем эти задачи решаются с помощью рекурсивного вызова или непосредственно, если их размер достаточно мал. Наконец, их решения комбинируются, и получается решение исходной задачи. Алгоритм был изобретён Джоном фон Нейманом в 1945 году.

Странно, но мне показалось, что данный алгоритм не так сильно освещён в интернете в целом и на python  в частности. А ведь именно этот алгоритм чаще всего применяется для сортировки данных не помещающихся в оперативке, т.е. хранящихся в файлах(внешние сортировки). Как и в случае с быстрой сортировкой Хоара, существует 2 реализации данного алгоритма. Рекурсивная и нет) Скажу по секрету, не рекурсивную реализацию мне предоставил так же мой преподаватель Деон. Более того, она ещё и не требует дополнительной памяти, что в классическом варианте относят к её основным минусам!

Для решения задачи сортировки эти три этапа выглядят так:
  1. Сортируемый массив разбивается на две части примерно одинакового размера;
  2. Каждая из получившихся частей сортируется отдельно, например — тем же самым алгоритмом;
  3. Два упорядоченных массива половинного размера соединяются в один.
Рекурсивное разбиение задачи на меньшие происходит до тех пор, пока размер массива не достигнет единицы (любой массив длины 1 можно считать упорядоченным).
Нетривиальным этапом является соединение двух упорядоченных массивов в один. Основную идею слияния двух отсортированных массивов можно объяснить на следующем примере. Пусть мы имеем две стопки карт, лежащих рубашками вниз так, что в любой момент мы видим верхнюю карту в каждой из этих стопок. Пусть также, карты в каждой из этих стопок идут сверху вниз в неубывающем порядке. Как сделать из этих стопок од