реклама на сайте
подробности

 
 
14 страниц V  « < 6 7 8 9 10 > »   
Reply to this topicStart new topic
> Кризис в самообразовании.
dxp
сообщение Mar 28 2017, 11:28
Сообщение #106


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Сортировка in-place:

CODE
#!/usr/bin/python3

rnd =  [40,14,17,46,12,53,3,49,26,56,10,28,59,20,35,42,42,18,24]

rnd.sort(key=lambda x: -1*x if x & 0x1 else x, reverse=True)

print (rnd)


CODE
hz@h:~/slon/python/$ ./sort2.py
[56, 46, 42, 42, 40, 28, 26, 24, 20, 18, 14, 12, 10, 3, 17, 35, 49, 53, 59]

Этот вариант и работать должен быстрее. Хотя он не такой наглядный для неподготовленного человека.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
=SSN=
сообщение Mar 28 2017, 11:31
Сообщение #107


Частый гость
**

Группа: Участник
Сообщений: 161
Регистрация: 9-09-08
Из: РФ
Пользователь №: 40 076



Цитата(Swup @ Mar 28 2017, 14:17) *
ПС понравилась функция сравнения у вас. Мне и в голову не пришло, что так можно.

Указатель на функцию-предикат можно также и на С++ использовать:
Код
// Return whether first element is greater than the second
bool greater ( int a, int b )
{
   return (a&1 == 0)&&(b&1 == 0)&&(a < b)||(a&1 == 1)&&(b&1 == 1)&&(a > b)||(a&1 == 1)&&(b&1 == 0);
}

sort( vec.begin( ), vec.end(), greater);

См. msdn

Сообщение отредактировал =SSN= - Mar 28 2017, 11:52
Go to the top of the page
 
+Quote Post
Guest_TSerg_*
сообщение Mar 28 2017, 11:54
Сообщение #108





Guests






Цитата(dxp @ Mar 28 2017, 14:28) *
rnd.sort(key=lambda x: -1*x if x & 0x1 else x, reverse=True)
..
Хотя он не такой наглядный для неподготовленного человека.

Да, с лямбда-функцией это практически идеальный по краткости вариант.
Нечто подобное было предложено на PascalABC.Net (там тоже lambda есть), но студент выбрал из предложенных все же вариант с декомпозицей на четные-нечетные и раздельной их сортировкой пузырьком на месте.
Так ему понятнее.

Код
// Body  
  var k: integer = 0;
  var x: integer;
  
// Even to head
  for var i := 0 to ar.High do
    if not Odd(ar[i]) then begin
        x := ar[i];
        for var j := i downto k+1 do
          ar[j] := ar[j-1];
        ar[k] := x;
        Inc(k);
    end;
// Sort even
  for var i := 0 to k-2 do
    for var j := i to k-1 do
      if ar[i] < ar[j] then Swap(ar,i,j);
// Sort odd
  for var i := k to ar.High-1 do
    for var j := i to ar.High do
      if ar[i] > ar[j] then Swap(ar,i,j);


Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 28 2017, 12:18
Сообщение #109


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Замерил производительность, сортировка 1000000 рандомов в диапазоне 0..100000. Первый вариант (с вычленением чётных-нечётных и раздельной сортировкой):

1.0882549455855042

второй, по ключу:

0.48738399290014056

Более, чем в два раза.

P.S. Вариант с лямбдой работает только с натуральными числами. Если надо весь целый диапазон, то ключевую функцию надо поправить соответственно.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Swup
сообщение Mar 28 2017, 12:27
Сообщение #110


Частый гость
**

Группа: Свой
Сообщений: 127
Регистрация: 2-09-11
Из: Москва
Пользователь №: 66 970



Цитата(ViKo @ Mar 28 2017, 15:26) *
Почему не на месте? В книге Шилдта есть такой код:


Спасибо, что поправили.
Какие-то у меня в голове странные ассоциации сложились по поводу "на месте" и "O(1) потребления памяти".
Go to the top of the page
 
+Quote Post
aiwa
сообщение Mar 28 2017, 13:16
Сообщение #111


Местный
***

Группа: Участник
Сообщений: 301
Регистрация: 13-12-15
Из: Харьков
Пользователь №: 89 682



Цитата(dxp @ Mar 27 2017, 10:43) *
А уж про синтаксические правила и говорить нечего. Ведь это же надо придумать конструкции вроде такой:

int (*(af[]))(int);

Ведь тут без бутылки не разберёшься. Нет, чтоб читать выражение слева-направо, тут надо расшифровывать по специальным правилам, а всего-то массив указателей на функции. Конечно, человек ко всему привыкает, но новичкам это срывает крышу.


Можно разобраться и без бутылки, если помнить, что в С разбор не слева-направо или наоборот, а по спирали.

Берем идентификатор и вокруг него раскручиваем спиральку:
af /*af - идентификатор*/
[] /*значит, af - это массив*/
* /*значит, это массив указателей на...*/
(int) /* скобки - принадлежность функции, внутри скобок - ее параметры, значит массив указателей на функции принимающие в качестве параметра тип int */
int /* тип возращаемого результата вышеупомянутыми функциями, ...... */

Сообщение отредактировал aiwa - Mar 28 2017, 13:17
Go to the top of the page
 
+Quote Post
AlexandrY
сообщение Mar 28 2017, 19:44
Сообщение #112


Ally
******

Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050



Цитата(dxp @ Mar 27 2017, 18:24) *
Было сказано, чтобы читабельно и понимабельно бегиннерам - т.е. разумная декомпозиция. Но для любителей говнокода, извольте:
Код
res  = sorted([x for x in rnd if not x%2], reverse=True) + sorted([x for x in rnd if x%2])

Нет, ну действительно у создателей питона не было целью сделать жизнь легче.

Вот пример на Node.js -
Код
var math = require('mathjs');

var  X = math.matrix([40, 14, 17, 46, 12, 53, 3, 49, 26, 56, 10, 28, 59, 20, 35, 42, 42, 18, 24]);
A = math.concat(math.sort(math.filter(X, function (x){ return x%2 == 0 }),'desc'),math.sort(math.filter(X, function(x){ return x%2 > 0})))

console.log(A);
Все ясно и понятно. Я это сделал за 10 мин, до этого никогда Node.js в руках не держал.

А вооще-то мы ждем перлов на ассемблере. Кто тут рвался показать счастье. biggrin.gif

Да нет, я не тролю. Тема мне не интересна, просто только что мне пришла ссылка с рекламой Node.js для embedded,
где довольно изящно опустили Python - http://embedded-computing.com/articles/spe...-using-node-js/
Go to the top of the page
 
+Quote Post
Guest_TSerg_*
сообщение Mar 28 2017, 21:01
Сообщение #113





Guests






Цитата(AlexandrY @ Mar 28 2017, 22:44) *
.. до этого никогда Node.js в руках не держал.

Кто хорошо освоил один из ЯП, нет проблем перейти на другой.
Точнее, проблемы будут, но не с синтаксисом, а либами.
P.S.
Питон - это не панацея, но один из вариантов современных языковых технологий.


Нда.. наверное самый короткий и понятливый вариант на PascalABC.Net (используются лямбды):
Есть конечно, фикус - массив остается прежним sm.gif

Код
begin
  var ar := Seq(45,46,8,11,5,29,37,0,21,43,4,5,58,34,14,18,40,46,30);
  ar.Where(x -> x mod 2 = 0).SortedDescending.Print;
  Print('');
  ar.Where(x -> x mod 2 <> 0).Sorted.Print;
end.


Result:
Код
45 46 8 11 5 29 37 0 21 43 4 5 58 34 14 18 40 46 30
58 46 46 40 34 30 18 14 8 4 0 5 5 11 21 29 37 43 45
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 29 2017, 04:00
Сообщение #114


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (AlexandrY @ Mar 29 2017, 02:44) *
Нет, ну действительно у создателей питона не было целью сделать жизнь легче.

Конечно! Питон - один из самых внятных и простых в освоении языков и при этом невероятно мощный и гибкий. Но вы-то его не знаете ни разу, а поливать дерьмом то, что с чем не удосужились познакомиться даже поверхностно, это ваша фирменная фишка. Это касается и С++, и систем управления версиями, а вот теперь ещё и питон.

QUOTE (AlexandrY @ Mar 29 2017, 02:44) *
Вот пример на Node.js -
CODE
var math = require('mathjs');

var  X = math.matrix([40, 14, 17, 46, 12, 53, 3, 49, 26, 56, 10, 28, 59, 20, 35, 42, 42, 18, 24]);
A = math.concat(math.sort(math.filter(X, function (x){ return x%2 == 0 }),'desc'),math.sort(math.filter(X, function(x){ return x%2 > 0})))

console.log(A);
Все ясно и понятно. Я это сделал за 10 мин, до этого никогда Node.js в руках не держал.

Что тут ясно и понятно? Какое-то нагромождение "проприетарных" ключевых слов. При этом длинно и рыхло. Уже приводил выше, но повторю:
CODE
rnd.sort(key=lambda x: -1*x if x & 0x1 else x, reverse=True)

Сделайте хотя бы так же компактно. Хотя, думается, вы не понимаете, как это работает.

QUOTE (AlexandrY @ Mar 29 2017, 02:44) *
А вооще-то мы ждем перлов на ассемблере. Кто тут рвался показать счастье. biggrin.gif

Про асм тоже не в кассу. Во-первых, все поняли контекст того поста (ну, кроме вас, видимо). Во-вторых, вся фишка этих кратких и красивых вариантах на ЯВУ - в использовании библиотек. Напишите сортировку на любом из этих языков без использования библиотечных функций - чисто выражениями языка - и увидите, что на асме оно будет не сильно отличаться, потому что тут нет ни каких-либо высокоуровневых абстракций, ни сколько-нибудь сложной структуры программы.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Guest_TSerg_*
сообщение Mar 29 2017, 15:58
Сообщение #115





Guests






Цитата(dxp @ Mar 29 2017, 07:00) *
.. вся фишка этих кратких и красивых вариантах на ЯВУ - в использовании библиотек.

Не только.
Есть такие понятия, как "синтаксический сахар" и "синтаксическая соль".
Применение первого, обеспечивает, по выражению Джек Криншоу:
"В конце концов, люди тоже должны читать программы… Сахарные токены служат в качестве полезных ориентиров, помогающих вам не сбиться с пути…"
Сам термин "syntactic sugar" был введен Peter J. Landin в 1964 г. для описания синтаксиса алголо-подобного языка с использованием лямбда-исчисления.
Пример во многих ЯВУ - дополнение базового безусловного цикла, сначала тремя циклами (пред-, пост-условие, цикл с шагом), а затем и foreach.
Или, к примеру (x := x + y) == (x+=y); Это стандартно для C, но для Pascal - нет. Тем не менее, отечественные разработчики PascalABC.Net, сознательно пошли на значительную переделку Object Pascal, для сближения его с современными технологиями.

Синтаксическая "соль" - дополнительные, технически бесполезные, конструкции в языке программирования, которые правила языка требуют употреблять при выполнении потенциально небезопасных действий.
Пример в Delphi - override.
Или, например - завершение операции точкой с запятой.
Для синтаксического парсера, это не принципиально, но большинство разработчиков к этому привыкли.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Mar 30 2017, 10:12
Сообщение #116


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(TSerg @ Mar 29 2017, 18:58) *
Или, к примеру (x := x + y) == (x+=y); Это стандартно для C, но для Pascal - нет.

Это имеет конечный смысл, особенно на безаккумуляторных архитектурах.
Так же, как ++ и --


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
petrov
сообщение Mar 30 2017, 14:20
Сообщение #117


Гуру
******

Группа: Свой
Сообщений: 2 220
Регистрация: 21-10-04
Из: Balakhna
Пользователь №: 937



Цитата(TSerg @ Mar 29 2017, 18:58) *
Или, к примеру (x := x + y) == (x+=y); Это стандартно для C, но для Pascal - нет. Тем не менее, отечественные разработчики PascalABC.Net, сознательно пошли на значительную переделку Object Pascal, для сближения его с современными технологиями.


Просто таки замечательный пример тарабарщины на ровном месте, в большинстве современные языки превратились в совершенно нечитабельную вещь в себе, в отличие от старых книг с алгоритмами на фортране и паскале. ИМХО
Go to the top of the page
 
+Quote Post
Guest_TSerg_*
сообщение Mar 31 2017, 18:29
Сообщение #118





Guests






Цитата(petrov @ Mar 30 2017, 17:20) *
Просто таки замечательный пример тарабарщины на ровном месте, в большинстве современные языки превратились в совершенно нечитабельную вещь в себе, в отличие от старых книг с алгоритмами на фортране и паскале. ИМХО

BASIC - наше все, с нумерацией строк, GOSUB и полной свободой.
Go to the top of the page
 
+Quote Post
Guest_TSerg_*
сообщение Apr 4 2017, 17:12
Сообщение #119





Guests






Еще один, очень красивый и, практически, кросс-языковый вариант решения задачи сортировки четных-нечетных:
(хотя он подразумевает, что изначально числа заданы в положительном диапазоне)

Код
for (int i = 0; i < rnd.Length; i++) if (rnd[i] % 2 == 0) rnd[i] = rnd[i] * (-1);
Array.Sort(rnd);
for (int i = 0; i < rnd.Length; i++) if (rnd[i] % 2 == 0) rnd[i] = rnd[i] * (-1);
Go to the top of the page
 
+Quote Post
dxp
сообщение Apr 5 2017, 03:20
Сообщение #120


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



QUOTE (TSerg @ Apr 5 2017, 00:12) *
Еще один, очень красивый и, практически, кросс-языковый вариант решения задачи сортировки четных-нечетных:
(хотя он подразумевает, что изначально числа заданы в положительном диапазоне)

CODE
for (int i = 0; i < rnd.Length; i++) if (rnd[i] % 2 == 0) rnd[i] = rnd[i] * (-1);
Array.Sort(rnd);
for (int i = 0; i < rnd.Length; i++) if (rnd[i] % 2 == 0) rnd[i] = rnd[i] * (-1);

Ну, так в варианте в посте №106 именно этот финт и использован. И тоже только для положительных целых. Для любых целых это трансформируется в
CODE
rnd.sort(key=lambda x: (1, -1*x) if x & 0x1 else (0, x), reverse=True)


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post

14 страниц V  « < 6 7 8 9 10 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 20:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01479 секунд с 7
ELECTRONIX ©2004-2016