Перейти к содержимому
  • 0
Stinger

Сортировка в Lua!

Вопрос

Здравствуйте форумчане, хочу сделать топ 3 на lua обязательно, весь состав записывается в файл:

 

Вот таким образом

 

//Ник,Очки

 

Test,15

Artem,26

Denis,111

Vlad, 22

 

и тд, думаю суть объяснил.

 

Записывает всё отлично!

 

Проблема в том, как вывести этот самый ТОП в таком виде:

 

Denis,111

Atrem,26

Vlad,22

 

Уже голову сломал, буду очень признателен за вашу помощь

Изменено пользователем Stinger

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Рекомендуемые сообщения

Ну думаю с чтением из файла разберешся. А насчет сортировки то тут все просто.
Пусть в массиве 'a' содержатся баллы

a={76,2,15,111}
max = a[1] --предположим что первое значение самое большое
for i = 1, #a do --пробегаем весь массив
  if a[i]>max then --если ¡-тый элемент будет больше max
    max = a[i] --перезаписываем переменную max
  end
end
print(max)--выводим максимальное значение

Ну а так как тебе надо вывести 3 значения тут уже можно подумать. Лично я бы запустил поиск 3 раза удаляя из массива те значения которые уже были выведены.

local function max3(a)
  local b, s = {}, {} --2 массива где b-для запоминания мах элемента, а s-для запоминания номера где этот элемент содержится
  for i=1,3 do
    s[#s+1] = 1; --счетчик
    b[#b+1] = a[1] --предположим что первое значение самое большое
    for i = 1, #a do --пробегаем весь массив
      if a[i]>b[#b] then --если ¡-тый элемент будет больше max
        b[#b] = a[i] --перезаписываем переменную
        s[#s] = i --запоминаем максимальный номер в массиве 
      end
    end
    a[s[#s]] = 0 --обнуляем максимальный элемент массива чтобы больше в поиск не лез
  end
  --print(#b..#s)
  return b, s --возвращаем массивы
end

name = {'вася','петя','маша','даша'}
points = {76,2,15,111}
maxPoints = {}
maxName = {}

maxPoints, maxName = max3(points)
for i=1,#maxName do --приводим к нормальному виду массив
  maxName[i] = name[maxName[i]]
end
for i =1, #maxName do --выводим результат
  print(maxName[i]..' заработал '..maxPoints[i]..' баллов')
end

итого получилась небольшая функция которая на выходе выдает 2 массива с 3 значениями, один массив придется немного обработать, чтобы он правильно выводил результаты.

Собственно это мое мнение и мой код, у других он будет другой

Изменено пользователем Asior

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ну думаю с чтением из файла разберешся. А насчет сортировки то тут все просто.

Пусть в массиве 'a' содержатся баллы

a={76,2,15,111}

max = a[1] --предположим что первое значение самое большое

for i = 1, #a do --пробегаем весь массив

if a>max then --если ¡-тый элемент будет больше max

max = a --перезаписываем переменную max

end

end

print(max)--выводим максимальное значение

*код оформлю как до компа доберусь

Ну а так как тебе надо вывести 3 значения тут уже можно подумать. Лично я бы запустил поиск 3 раза удаляя из массива те значения которые уже были выведены.

*тут будет этот код

итого получилась небольшая функция которая на выходе выдает массив с 3 значениями.

 

Хорошая идея, спасибо, но есть не большой нюанс, из таблицы потеряются Ники этого топа.

И вот с 1 числом понятно, оно будет самое большое,а вот второе как оформить и третье ?

Изменено пользователем Stinger

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Хорошая идея, спасибо, но есть не большой нюанс, из таблицы потеряются Ники этого топа.

И вот с 1 числом понятно, оно будет самое большое,а вот второе как оформить и третье ?

А как удалять те которые уже были проверенны ?

 

Всё понял сам.

Изменено пользователем Stinger

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Итак.

Дано:

Файл формата "НИК,ОЧКИ" по строку на каждую запись.

Путь к файлу: /etc/scores.csv

Задача:

Прочитать файл, отсортировать по очкам и вывести первые 3 записи.

 

Решаем!

Во-первых, прочтём файл. Так как у нас всё по строкам, можно использовать функцию io.lines. Т.е. что-то типа такого потребуется:

for line in io.lines("/etc/scores.csv") do
  -- здесь обработчик
end

Строку надо разделить на две части, побив на запятой. Здесь нам помогут шаблоны.

Выглядеть это будет как-то так:

local player, score = line:match("^(.*),([0-9]+)$")

-- score у нас будет в виде текстовой переменной, поэтому переведём её в числовую
score = tonumber(score)

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

Вне цикла создадим массив scores, а внутри цикла будем туда помещать пары "ник-очки". Как-то так:

local scores = {}

for line in io.lines("/etc/scores.csv") do
  local player, score = line:match("^(.*),([0-9]+)$")
  score = tonumber(score)
  table.insert(scores, {player, score})
end

Итак, с чтением из файла разобрались.

 

Теперь надо отсортировать таблицу. Если бы это была просто таблица типа {1, 100, 25}, мы бы могли воспользоваться table.sort. Но у нас в качестве значений таблицы ещё одни таблицы. То есть так: {{"Vasya", 100}, {"Ivan", 121}, {"moo", 9}}.

Обратимся к мануалу:


 

Sorts list elements in a given order, in-place, from list[1] to list[#list]. If comp is given, then it must be a function that receives two list elements and returns true when the first element must come before the second in the final order (so that, after the sort, i < j implies not comp(list[j],list)). If comp is not given, then the standard Lua operator < is used instead.

Note that the comp function must define a strict partial order over the elements in the list; that is, it must be asymmetric and transitive. Otherwise, no valid sort may be possible.

The sort algorithm is not stable: elements considered equal by the given order may have their relative positions changed by the sort.

Ага! Можно задать функцию, которая будет сортировать элементы.

Работает она так: функции передаётся пара элементов, а она возвращает false, если нужно их поменять местами.

Когда нам не нужно менять элементы местами? Когда элемент слева больше или равен элементу справа: нам же нужно отсортировать от большего к меньшему. То есть сделать что-то вроде оператора >=, который будет сравнивать очки.

 

Почему бы и нет. Вот как это будет выглядеть:

table.sort(scores, function(lhs, rhs)
  return lhs[2] >= lhs[2]
end)

Здесь я использую безымянную функцию, которая сразу передаётся в table.sort, чтобы не городить код.

 

Теперь нужно просто выввести первые три записи на экран.

Воспользуемся очень удобной функцией table.concat, которая возвращает строку, склеенную из элементов переданной таблицы, используя в качестве разделителя данным символ (например, table.concat({"hello", "world", 42}, " ") вернёт "hello world 42"):

for i = 1, 3, 1 do
  -- Может случиться так, что в файле будет меньше 3 строк,
  -- поэтому проверяем, что мы не вышли за пределы.
  if not scores[i] then
    -- Если всё же вышли, то прерываем цикл.
    break
  end
  print(table.concat(scores[i], ","))
end

Задача выполнена. Итоговый код:

local scores = {}

for line in io.lines("/etc/scores.csv") do
  local player, score = line:match("^(.*),([0-9]+)$")
  score = tonumber(score)
  table.insert(scores, {player, score})
end

table.sort(scores, function(lhs, rhs)
  return lhs[2] >= lhs[2]
end)

for i = 1, 3, 1 do
  if not scores[i] then
    break
  end
  print(table.concat(scores[i], ","))
end
Изменено пользователем Fingercomp

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо огромное, что такие отзывчивые люди есть, попробую собрать это всё в кучу и сделать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

 

table.sort(scores, function(lhs, rhs) return lhs[2] >= lhs[1] end)

 

Не верю! Если только так:

table.sort(scores, function(lhs, rhs) return lhs[2] >= rhs[2] end)
Остальное, вроде, должно работать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Не верю! Если только так:

table.sort(scores, function(lhs, rhs) return lhs[2] >= rhs[2] end)
Остальное, вроде, должно работать.

 

Да, очепятался. Люблю это делать.

Поправил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Спасибо, всё работает, очень помогли, если не сложно подскажите хорошую литературу по Lua.

Изменено пользователем Stinger

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Все книги находятся на главной странице в правой колонке.

66Wbakp.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Большое спасибо всем, кто помогал!

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить на вопрос...

×   Вы вставили отформатированное содержимое.   Удалить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.


×
×
  • Создать...