-
Notifications
You must be signed in to change notification settings - Fork 0
070_lesson #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
070_lesson #7
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| import random | ||
|
|
||
| N = 10 | ||
|
|
||
| a = [0] * N | ||
| for i in range(N): | ||
| a[i] = random.randrange(-100, 100) | ||
| print(f'raw_list = {a}') | ||
|
|
||
| for i in range(N - 1): | ||
| # print('#' * 66) | ||
| # print(i) | ||
| for j in range(N - 1 - i): | ||
| # print('*' * 66) | ||
| # print(j) | ||
| if a[j] > a[j + 1]: | ||
| a[j], a[j + 1] = a[j + 1], a[j] | ||
|
|
||
| print(f'sorted a = {a}') | ||
| a_reverse = sorted(a, reverse=True) | ||
| print(f'sorted and reversed = {a_reverse}') | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import random | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Это сортировка слиянием? ))) |
||
|
|
||
| N = 10 | ||
|
|
||
|
|
||
| def sum_(m): | ||
| s = 0 | ||
| while m > 0: | ||
| s += m % 10 | ||
| m = m // 10 | ||
| return s | ||
|
|
||
|
|
||
| a = [0] * N | ||
| for i in range(N): | ||
| a[i] = random.randrange(0, 50) | ||
| print(a) | ||
|
|
||
| for i in range(N - 1): | ||
| for j in range(N - 1 - i): # i in first loop is 0 | ||
| if sum_(a[j]) > sum_(a[j + 1]): | ||
| a[j], a[j + 1] = a[j + 1], a[j] | ||
|
|
||
| print(a) | ||
| a_result = [] | ||
| for i in range(N): | ||
| a_result.append(sum_(a[i])) | ||
| print(f'{a_result}') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Прочитал до конца код. Абсолютно уверен, что это не сортировка. Результаты вывода на экран подтверждают моё мнение. Что же это? ))) |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| import random | ||
|
|
||
| M = 10 | ||
| N = 2 * M + 1 | ||
|
|
||
| l = [0] * N | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| for i in range(N): | ||
| l[i] = random.randrange(0, 100) | ||
| print(f'raw_list = {l}') | ||
| x = sorted(l[:]) | ||
| print(f'sorted_list = {x}') | ||
|
|
||
| # With love to https://habr.com/post/346930/ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ))) |
||
|
|
||
| def nlogn_median(l): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Простое решение со встроенной сортировкой. |
||
| n = len(l) | ||
| if n % 2 == 1: | ||
| return sorted(l)[n // 2] | ||
| else: | ||
| return sum(sorted(l)[n // 2 - 1: n // 2 + 1]) / 2.0 | ||
|
|
||
|
|
||
| def quickselect_median(l, pivot_fn=random.choice): | ||
| if len(l) % 2 == 1: | ||
| return quickselect(l, len(l) / 2, pivot_fn) | ||
| else: | ||
| return 0.5 * (quickselect(l, len(l) / 2 - 1, pivot_fn) + | ||
| quickselect(l, len(l) / 2, pivot_fn)) | ||
|
|
||
|
|
||
| def quickselect(l, k, pivot_fn): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Примерно это будет на разборе ДЗ |
||
| """ | ||
| Выбираем k-тый элемент в списке l (с нулевой базой) | ||
| :param l: список числовых данных | ||
| :param k: индекс | ||
| :param pivot_fn: функция выбора pivot, по умолчанию выбирает случайно | ||
| :return: k-тый элемент l | ||
| """ | ||
| if len(l) == 1: | ||
| assert k == 0 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. В половине запусков выпадаю тут с ошибкой |
||
| return l[0] | ||
|
|
||
| pivot = pivot_fn(l) | ||
|
|
||
| lows = [el for el in l if el < pivot] | ||
| highs = [el for el in l if el > pivot] | ||
| pivots = [el for el in l if el == pivot] | ||
|
|
||
| if k < len(lows): | ||
| return quickselect(lows, k, pivot_fn) | ||
| elif k < len(lows) + len(pivots): | ||
| # Нам повезло и мы угадали медиану | ||
| return pivots[0] | ||
| else: | ||
| return quickselect(highs, k - len(lows) - len(pivots), pivot_fn) | ||
|
|
||
|
|
||
| def pick_pivot(l): | ||
| """ | ||
| Выбираем хорошй pivot в списке чисел l | ||
| Этот алгоритм выполняется за время O(n). | ||
| """ | ||
| assert len(l) > 0 | ||
|
|
||
| # Если элементов < 5, просто возвращаем медиану | ||
| if len(l) < 5: | ||
| # В этом случае мы возвращаемся к первой написанной нами функции медианы. | ||
| # Поскольку мы выполняем её только для списка из пяти или менее элементов, она не | ||
| # зависит от длины входных данных и может считаться постоянным | ||
| # временем. | ||
| return nlogn_median(l) | ||
|
|
||
| # Сначала разделим l на группы по 5 элементов. O(n) | ||
| chunks = chunked(l, 5) | ||
|
|
||
| # Для простоты мы можем отбросить все группы, которые не являются полными. O(n) | ||
| full_chunks = [chunk for chunk in chunks if len(chunk) == 5] | ||
|
|
||
| # Затем мы сортируем каждый фрагмент. Каждая группа имеет фиксированную длину, поэтому каждая сортировка | ||
| # занимает постоянное время. Поскольку у нас есть n/5 фрагментов, эта операция | ||
| # тоже O(n) | ||
| sorted_groups = [sorted(chunk) for chunk in full_chunks] | ||
|
|
||
| # Медиана каждого фрагмента имеет индекс 2 | ||
| medians = [chunk[2] for chunk in sorted_groups] | ||
|
|
||
| # Возможно, я немного повторюсь, но я собираюсь доказать, что нахождение | ||
| # медианы списка можно произвести за доказуемое O(n). | ||
| # Мы находим медиану списка длиной n/5, поэтому эта операция также O(n) | ||
| # Мы передаём нашу текущую функцию pick_pivot в качестве создателя pivot алгоритму | ||
| # quickselect. O(n) | ||
| median_of_medians = quickselect_median(medians, pick_pivot) | ||
| return median_of_medians | ||
|
|
||
|
|
||
| def chunked(l, chunk_size): | ||
| """Разделяем список `l` на фрагменты размером `chunk_size`.""" | ||
| return [l[i:i + chunk_size] for i in range(0, len(l), chunk_size)] | ||
|
|
||
| print(f'n*logn median = {nlogn_median(l)}') | ||
| print(f'quickselect_median = {quickselect_median(l, pivot_fn=random.choice)}') | ||
| print(f'determine O(n) = {pick_pivot(l)}') # что-то здесь пошло не так с медианой??? | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Привязка к |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Похоже вы прослушали то, что было в конце урока.
В функцию не превратили, "ускоритель" не добавили. И сортирует по возрастанию, а не по убыванию.
Да, разворот внизу есть. Но с таким же успехом можно все задачи решить через
sorted.