Рубиновые блоки и сортировка [дубликаты]

Как это исправить?

Эта ошибка означает, что JRE, который используется для выполнения вашего кода класса, не распознает используемую версию Java. Обычно, поскольку версия Java, которая сгенерировала ваш файл класса (т.е. скомпилировала его), является более новой.

Чтобы исправить это, вы можете либо

a) Скомпилировать ваши источники Java с тем же, или более старой версии компилятора Java, который будет использоваться для его запуска. т. е. установить соответствующий JDK.

b) Скомпилировать ваши источники Java с более новой версией компилятора Java, но в режиме совместимости. т.е. используйте параметр -target.

c) Запустите скомпилированные классы в JRE, которая является той же самой или новой версией, что и JDK, используемый для компиляции классов.

Вы может проверить версии, которые вы используете в настоящий момент с помощью javac -version для компилятора, и java -version для среды выполнения.

Должен ли я установить JDK и настроить свою переменную PATH на JDK вместо JRE?

Для компиляции, конечно же, установите и настройте конкретный JDK, который вы хотите.

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

В чем разница между переменной PATH в JRE или JDK?

Переменная среды PATH сообщает командной оболочке, где нужно искать введенную команду. Когда вы набираете java, интерпретатор командной оболочки будет просматривать все местоположения, указанные в переменной PATH слева направо, чтобы найти исполняемый файл исполняемого файла java для запуска. Если у вас есть несколько версий Java, то есть у вас есть исполняемый файл java в нескольких местах, указанных в переменной PATH, то первый, который встречается при движении слева направо, будет выполняться.

Команда компилятора javac и поставляется только с JDK. Команда runtime является java и поставляется с JDK и находится в JRE.

Вероятно, у вас установлена ​​одна версия (51.0 = Java 7) javac, и у вас также есть ту же версию java, но другая предыдущая версия java появляется раньше в PATH и поэтому вызывается вместо ожидаемого.

72
задан Mohsen Nosratinia 8 May 2015 в 14:20
поделиться

7 ответов

В вашем примере

a.sort

эквивалентно

a.sort { |x, y| x <=> y }

Как вы знаете, для сортировки массива вам нужно иметь возможность сравнивать его элементы (если вы сомните, что просто попробуйте реализовать любой алгоритм сортировки без какого-либо сравнения, нет <, >, <= или >=).

Предоставляемый вами блок действительно является функцией, которая будет вызывается алгоритмом sort для сравнения двух элементов. Это x и y всегда будут некоторыми элементами входного массива, выбранными алгоритмом sort во время его выполнения.

Алгоритм sort будет считать, что эта функция сравнения / блок будет соответствуют требованиям метода <=>:

  • return -1, если x & lt; y
  • возвращает 0, если x = y
  • возвращает 1, если x> y

Неспособность обеспечить адекватную функцию сравнения / блок приведет к массив, порядок которого не определен.

Теперь вы должны понять, почему

a.sort { |x, y| x <=> y }

и

a.sort { |x, y| y <=> x }

возвращают тот же массив в противоположных порядках.


Чтобы узнать, что добавил Тейт Джонсон, если вы реализуете функцию сравнения <=> на любом из ваших классов, вы получаете следующее

  1. Вы можете включить модуль Comparable в вашем классе, который автоматически определит для вас следующие методы: between?, ==, >=, <, <= и >.
  2. Экземпляры вашего класса теперь можно сортировать, используя вызов по умолчанию (то есть без аргумента) в sort.

Обратите внимание, что метод <=> уже предоставляется везде, где это имеет смысл в стандартной библиотеке Ruby (Bignum ], Array, File::Stat, Fixnum, String, Time и т. д.).

120
ответ дан bltxd 21 August 2018 в 12:11
поделиться
  • 1
    Я думаю, стоит добавить, что <=> - это метод, определенный в Comparable и смешанный с String. Fixnum и Bignum также определяют <=>. Вы можете реализовать <=> в любом классе, где необходимы сортировка или сопоставления. – Tate Johnson 14 April 2010 в 14:03
  • 2
    Я подчеркнул важное предложение. x и y будут 2 элементами вашего массива, выбранными самим алгоритмом сортировки. – bltxd 14 April 2010 в 14:19
  • 3
    Благодарю. Я получаю это сейчас! – Ibrahim Hussein 14 April 2010 в 14:38
  • 4
    Также хорошо заметить, что ваш блок может быть как можно сложнее или по мере необходимости. Пока возвращаемое значение точно отражает поведение, которое вы ожидаете от вашего & lt; = & gt; оператор, вы можете делать все, что вам нужно. Поэтому, если вы хотите сортировать на основе логического или что-то, вы можете оценить это логическое значение и вернуть -1 или 1 соответственно. Это пригодится. – Matthew 15 April 2010 в 00:07
  • 5
    FWIW, <=> известен как оператор Spaceship – B Seven 10 June 2014 в 21:19

Некоторые другие точки:

  • x и y называются параметрами блока. Метод сортировки в основном говорит: «Я дам вам x и y, вы определяете, должен ли x или y быть первым, и я буду следить за скучными вещами в отношении сортировки»
  • <=> называемый оператором космического корабля .
4
ответ дан Community 21 August 2018 в 12:11
поделиться

<=> - это метод ruby, который возвращает (self.<=>( argument ))

  • -1, если self & lt; аргумент
  • 0, если аргумент self ==
  • 1, если self> argument

x и y являются элементами массива. Если никакой блок не предусмотрен, функция sort использует x<=>y, в противном случае результат блока говорит, что если x должен быть до y.

array.sort{|x, y| some_very_complicated_method(x, y) }

Здесь, если some_very_complicated_method (x, y) возвращает smth то есть & lt; 0, х считается & lt; чем у и т. д. ...

6
ответ дан Draco Ater 21 August 2018 в 12:11
поделиться

@OscarRyz ответ прояснил мне много вопросов о том, как работает сортировка, esp

 { |x, y| y <=> x }

Исходя из моего понимания, я предоставляю здесь, каково будет состояние массива после каждого сравнение для вышеописанных результатов блока.

Примечание. Получена ссылка на печать значений параметров блока e1, e2 из ruby-forum

1.9.3dev :001 > a = %w(d e a w f k)
1.9.3dev :003 > a.sort { |e1, e2| p [e2, e1]; e2 <=> e1 }
["w", "d"]
["k", "w"]
["k", "d"]
["k", "e"]
["k", "f"]
["k", "a"]
["f", "a"]
["d", "f"]
["d", "a"]
["d", "e"]
["e", "f"]
 => ["w", "k", "f", "e", "d", "a"]

Угаданное состояние массива во время выполнения после каждого сравнения:

 [e2, e1]    Comparsion Result       Array State
["w", "d"]      1                   ["w", "e", "a", "d", "f", "k"]
["k", "w"]     -1                   ["w", "e", "a", "d", "f", "k"]
["k", "d"]      1                   ["w", "e", "a", "k", "f", "d"]
["k", "e"]      1                   ["w", "k", "a", "e", "f", "d"]  
["k", "f"]      1                   ["w", "k", "a", "e", "f", "d"]    
["k", "a"]      1                   ["w", "k", "a", "e", "f", "d"]  
["f", "a"]      1                   ["w", "k", "f", "e", "a", "d"]  
["d", "f"]     -1                   ["w", "k", "f", "e", "a", "d"]  
["d", "a"]      1                   ["w", "k", "f", "e", "d", "a"]  
["d", "e"]     -1                   ["w", "k", "f", "e", "d", "a"]  
["e", "f"]     -1                   ["w", "k", "f", "e", "d", "a"] (Result)

Спасибо,

Jignesh

7
ответ дан Jiggneshh Gohel 21 August 2018 в 12:11
поделиться

Я верю | x, y | y & lt; => x сравнивает два элемента за раз в порядке убывания, как показано в: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-3C -3D-3E Предположим, что сначала используются сравнения «d», «a», «e», «c», «b»], «d» и «a». Тогда, поскольку он нисходит, оба остаются в том же порядке, потому что d оценивается меньше, чем a. Затем оцениваются d и e. «e» перемещается в положение «d». Не зная внутренней работы кода c, невозможно узнать, где находится d, но я считаю, что этот процесс продолжается до тех пор, пока все элементы не будут отсортированы. Функции c:

           VALUE
rb_ary_cmp(VALUE ary1, VALUE ary2)
{
    long len;
    VALUE v;

    ary2 = rb_check_array_type(ary2);
    if (NIL_P(ary2)) return Qnil;
    if (ary1 == ary2) return INT2FIX(0);
    v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
    if (v != Qundef) return v;
    len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
    if (len == 0) return INT2FIX(0);
    if (len > 0) return INT2FIX(1);
    return INT2FIX(-1);
}
2
ответ дан Michael F 21 August 2018 в 12:11
поделиться

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

Но когда вы сортируете другие объекты, может потребоваться предоставить возможность сравнить (каждый) два из них. Допустим, у вас есть массив объектов класса Person. Вероятно, вы не можете определить, больше ли объект bob больше, чем объект mike (т. Е. Класс Person не имеет метода <=>). В этом случае вам нужно будет предоставить некоторый код, чтобы объяснить, в каком порядке вы хотите, чтобы эти объекты отсортировались по методу sort. Вот где блочная форма срабатывает.

people.sort{|p1,p2| p1.age <=> p2.age}
people.sort{|p1,p2| p1.children.count <=> p2.children.count}

и т. Д. Во всех этих случаях метод sort сортирует их одинаково - используется один и тот же алгоритм. Другое дело - логика сравнения.

20
ответ дан Mladen Jablanović 21 August 2018 в 12:11
поделиться
  • 1
    Нашел этот ответ гораздо полезнее, если честно. Картина говорит тысячу слов, и пример говорит тысячу строк объяснения. – Kevin Monk 19 March 2013 в 01:03
  • 2
    Примечание: people.sort{|p1,p2| p1.age <=> p2.age} можно переписать как people.sort_by{|p| p.age} – Cyoce 31 March 2016 в 22:07

In:

a.sort {|x,y| y <=> x }   #=> ["e", "d", "c", "b", "a"]

Что такое x и y?

x и y являются элементы сравниваются алгоритмом сортировки.

Это полезно для определения пользовательских классов, элемент которых должен быть перед другим.

Для основных данных (числа, строки, дата и т. д.) естественный порядок предопределен, но для элемента клиента (т. е. Employee) вы определяете, кто идет до того, кто сравнивается. Этот блок дает вам возможность определить это.

и что происходит при y & lt; => x?

Там они сравнивают элементы в порядке убывания (те с «более высоким» значением будет первым), а не естественным порядком (x<=>y)

Метод <=> означает «compareTo» и возвращает 0, если элементы эквивалентны, или < 0 если x идет раньше y или > 0, если x идет после y

3
ответ дан OscarRyz 21 August 2018 в 12:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: