Это - решение, скопированное посимвольно из упражнения №24 следующего курса, посвященного массивам. Да, там авторы не написали про “метод пузырька”, просто как-то нечаянно перескочили в предыдущих уроках с “прямого выбора” на “пузырек”. И да, не пройдя этот курс, крайне сложно делать практику для предыдущего курса (вложенные циклы, своп, операции с массивами и их длиной), но стоило ли…
И всякий случай, у меня вот такое решение получилось:
for (var i=0; i<numbers.length-1; i++)
{
var min = i;
for (var j=i+1; j<numbers.length; j++)
{
if (numbers[j]<numbers[min])
{min=j;
}
}
var swap=numbers[i];
numbers[i]=numbers[min];
numbers[min]=swap;
}
И откуда у вас такая уверенность что оно скопировано? Там задача не широкая,чтобы 150 видов кода было. Полтора месяца назад я только начинал понимать js и решил таким образом. А пишу я код на visual studio и всегда привожу в нормальный вид перед реализацией.
Ps.
Пользуюсь сейчас методом .sort
var numbers = [1, 2, 3, 4, 5, 6, 158, 200, 97, 33, 68];
numbers.sort(function (number1, number2) {
return number1 - number2;
});
Хм… Вы уверены, что стоит дополнительно привлекать внимание к этому? Ну ок, вот аргументы:
- Посимвольное совпадение - это конечно вероятно (нот-то всего 7), но…
- Вплоть до названий переменных из другого задания (usersByDay),
- С заменой исходного массива в стартовой задаче, на массив из другой задачи…
- …даже без мелкого изменения, чтобы доделать образец до требуемого решения.
А достаточно было 3 строки свопа вынести в другую часть цикла, и все, ноль вопросов
Уважаемый.
1.По материалу,надо учится и глупо было бы мною копировать чужой код.
2.Мой вопрос был к Deepspiral,чтобы понять материал,который мы изучаем стоит ли вообще учить,т.к. там писали что метод очень плохой и я засомневался стоит ли учить такой материал,который приводит к плохому коду.
3.В тот момент я особо не понимал сути решаемой задачи. Я знал алгоритм,который был задан в задаче,но не сумел бы его использовать в другой задаче,сейчас уже мое понимание стало шире и лучше.
4.Вопрос к вам. Вы пришли тут учится к новому или разводить кашу?
5.Еще раз,в уроке учат только делать по одному-двум алгоритмам,как еще делать по другому? И да я взял из других задач имена переменных,т.к. имя подошло к задаче. И если вы проходили курс по “Продвинуты javascript уровень 1”,то знайте,что надо давать переменным правильные имена.
6. Дальше я не буду вам ничего писать,т.к. я пришел сюда учится,а не копировать чужой код.
Ps. И чем же отличается ваш код
for (var i = 0; i < numbers.length - 1; i++) {
var min = i;
for (var j = i + 1; j < numbers.length; j++) {
if (numbers[j] < numbers[min]) {
min = j;
}
}
var swap = numbers[i];
numbers[i] = numbers[min];
numbers[min] = swap;
}
От моей
for (var i = 0; i <= usersByDay.length - 2; i++) {
var minValue = usersByDay[i];
for (var j = i + 1; j <= usersByDay.length - 1; j++) {
if (usersByDay[j] < minValue) {
minValue = usersByDay[j];
var swap = usersByDay[i];
usersByDay[i] = minValue;
usersByDay[j] = swap;
}
}
}
Что ваши 3 строки вне цикла for?
var swap = numbers[i];
numbers[i] = numbers[min];
numbers[min] = swap;
Ну смешно же…
С такой логикой я могу то же самое про вас написать и сказать,что только изменили область видимости и все.
Pss. И чем же отличается наш код от кода ТС???
for (var i = 0; i < numbers.length; i++) {
for (var j = i; j < numbers.length; j++) {
if (numbers[i] > numbers[j]) {
var temp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = temp;
}
}
}
А, то есть вы не видите разницы? Тогда действительно дальше и не о чем говорить, и незачем
Чем ваш код отличается от Сортировка выбором ?
Аяяй,вот откуда скопировали…
Смешно просто.
Если я не вижу разницу,лучше будьте компетентным и объясните,а не флудите. И разговор не о том,что я не понимаю,а о том,что вы пишете,что я скопировал код. Тогда и вы скопировали из соседнего топика.
Пол форума тогда тырят друг у друга код задачи…
Удачи!
И вам удачи! Но на всякий случай рекомендую хотя бы попытаться разобраться, что меняется в процессе работы цикла, в зависимости от положения строк со свопом
Вот. Уже другой разговор. А то пишете скопировал скопировал,не приятно же… Я не стал изучать,т.к. пишут что метод не очень медленный для работы с средними или большим кол-вом данных. В массивах же не только циферки,там еще объекты,другие массивы,строки,объекты с массивами и т.д. Таким подходом просто геморойно делать поиск/сортировку…
не могу продвинуться дальше при сортировке выборкой. возникает проблема если есть одинаковые числа в массиве.
var numbers = [ 34,115,22,34,12,1,34];
for (var j = 0; j < numbers.length; j++) {
var min = numbers[numbers.length - 1];
var indexMin;
for (var i = j; i < numbers.length; i++) {
if (min > numbers[ i ]) {
min = numbers[ i ];
console.log( 'min: ’ + min);
var indexMin = numbers.indexOf( min );
console.log('minIndex: ’ + indexMin);
} else if (min === numbers[ i ]) {
var indexMin = numbers.indexOf(min);
}
}
var swap = numbers[ j ];
numbers[ j ] = numbers[indexMin];
numbers[ indexMin ] = swap;
console.log(numbers);
}
Товарищи, помогите, пожалуйста, разобраться.
Тут приводили решение:
var numbers = [3, 5, 15, 6, 2, 1];
var sort = [];
for (var i = 0; i < numbers.length; i++) {
for (j = i; j < numbers.length; j++) {
if (numbers[j] < numbers[i]) {
var tmp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = tmp;
}
}
}
Объясните, пожалуйста, как это работает? А именно, зачем нужен второй цикл внутри первого? С виду оба цикла проходятся по одному и тому же массиву и выполняют одни и те же действия. Однако код работает — сортировка происходит от меньшего к большему, — но почему работает этот код и зачем нужен второй цикл я не могу понять. Надеюсь, что кто-нибудь поможет разобраться.
Почему 2 цикла - нам нужно каждый элемент сравнить с каждым. Один проход позволит сравнить каждый элемент массива с каким-то определенным элементом, а нам нужно сравнить все со всеми.
var numbers = [3, 5, 15, 6, 2, 1];
var sort = [];
for (var i = 0; i < numbers.length; i++) {
for (j = i; j < numbers.length; j++) {
if (numbers[j] < numbers[i]) {
var tmp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = tmp;
}
}
}
Смотрите что у нас происходит.
3, 5, 15, 6, 2, 1
Сначала мы попадаем во внешний цикл, где i присваивается 0.
i = 0;
если вызовем тут console.log(numbers[i]) то получим тройку, первый элемент массива.
Дальше мы попадаем во внутренний цикл, где j у нас присваивается i.
Т.е. j = 0. numbers[j] опять даст 3 - первый элемент массива.
3 не меньше 3 (хм… и зачем мы сравниваем элемент сам с собой, возможно, нам стоило сразу начать со следующего?),
а значит условие не выполнится и мы пойдем на следующий круг цикла.
Т.е. j = 1 numbers[j] даст 5, второй элемент массива.
i у нас по прежнему 0 (помним внешний цикл), а numbers[i] - первый элемент массива.
5 не меньше 3, значит следующее условие не выполняется и мы опять наращиваем счетчик j.
Если визуализировать, то мы делали следующее -
мы попарно сравнивали каждый элемент с первым элементом массива. И если текущий оказывался меньше первого, то мы меняли их местами.
Наш массив:
3, 5, 15, 6, 2, 1
т.е. сначала 2 поменяется с 3
2 5 15 6 3 1
а потом 1 поменяется с 2
1 5 15 6 3 2
Ок, дошли до конца внутреннего цикла, опять вернулись во внешний.
i = 1, numbers[i] - второй элемент массива, т.е 5.
Зашли во внутренний цикл
j = 1, numbers[j] - опять второй элемент массива, т.е 5.
мы опять 5 сравниваем с 5 (хотя казалось бы зачем)
5 не меньше 5, переходим на следующий виток цикла
j = 2, numbers[j] = 15
15 не меньше 5, значит опять наращиваем j.
Что мы делали - мы сравнивали попарно второй элемент массива. Мы каждый раз сдвигаем область сравнения на 1 элемент (т.е. берем хвостик). После каждого прохода внешнего цикла мы получаем один правильно отсортированный элемент.
сейчас у нас так:
1 5 15 6 3 2
сначала 3 поменяется с 5
1 3 15 6 5 2
а потом 2 поменяется с 3
1 2 15 6 5 3
Закончили внутренний цикл - опять идем во внешний.
i = 2, третий эл-т массива
Сравниваем попарно начиная с 3-го и переставляем.
и т.д.
Все очень логично:
Находим минимум - ставим в начало (переставляем старые значения на освободившееся место, чтобы не пропали)
Из оставшихся (сдвинули на один) опять попарно находим минимум - ставим в начало. (нам же надо выстроить последовательно)
Из оставшихся (сдвинули на один) опять попарно находим минимум - ставим в начало.
…
Добавил визуализации в код.
Смысл в том, что все элементы перебираются в цикле. И на каждой итерации такого “внешнего” цикла, происходит запуск “внутреннего” цикла, в котором происходит перестановка циферей. Суть условия в том, что если текущее число из позиции номера итерации “внешнего” цикла больше какого то числа из списка “внутреннего” цикла, то они меняются местами через буферную переменную tmp.
var numbers = [3, 5, 15, 6, 2, 1];
for (var i = 0; i < numbers.length; i++) {
console.log('Массив выглядит так перед каждой внешней итерацией ' + numbers);
for (j = i; j < numbers.length; j++) {
if (numbers[j] < numbers[i]) {
var tmp = numbers[i];
numbers[i] = numbers[j];
numbers[j] = tmp;
}
console.log('А вот так выглядит после каждой внутренней итерации ' + numbers);
}
}
console.log('Конечный итог: ' + numbers);
zateya, Hierumo — спасибо вам огромное!
Теперь я понял, как работает этот код.
У вас тоже работает не так, как должно.
У вас двойка заняла первую позицию в массиве, когда сначала должна там появиться единица, как наименьший элемент.
Вот как следует переписать ваш код:
После внутреннего цикла массив не меняется, он нужен, для нахождения минимального элемента. Изменение массива происходит только во внешнем цикле, когда найденный наименьший элемент меняется местами с исходным.
смотрите, мы же обсуждали конкретный код, приведенный @ haosmos, который хотел понять как работает приведенный код.
Конечно, реальная сортировка выбором не меняет каждый раз (это уже даже выше указали), а меняет уже после нахождения минимума, когда прошлись по внутреннему циклу.
Действительно, нет нужды делать промежуточные перестановки до нахождения минимума.
Но вы молодец, что указали. Потому что обсуждение длинное и можно сразу не понять.
В общем, ваше замечание и решение правильное. Но Кирилл пояснял именно конкретный код. Важно же понять как работает решение, пусть оно даже не оптимальное и содержит лишние шаги.
Так-то я сам до конца разобрался с решением, только когда исправил код приведенный Кириллом. Так что я больше это себе объяснял
Вот да, Кирилл сделал отличную работу, т.е. подготовил все что нужно, чтобы сделать правильные выводы и найти оптимальное решение.
так то для сортировки есть метод для массивов .sort( (a,b) => a - b), он немного иначе работает и дает меньше итераций, если уж интересует самое оптимальное решение (ток его тут не преподают).
также можно было бы во внутреннем цикле сделать старт счетчика не j = i, а j = i + 1, так тоже меньше итераций будет (из того, что учили тут).
Счетчик я так и выставил в исправленном варианте j = i + 1 для внутреннего.
А методы sort использует алгоритм быстрой сортировки, что даже по условию задачи - не подходит. Ну и методы сейчас пока использовать - так себе идея. Нужно хотя бы элементарные алгоритмы разобрать и своими ручками их реализовать на практике.