Вернуть большее значение кортежа

Я пытаюсь найти режим списка, и вернуть кортеж режима и количество раз, когда это происходит в списке. У меня это до такой степени, что я могу вернуть список каждого числа и количество раз, которое это происходит после этого, но это также дает мне вхождения после первого,

fun counter(_, nil) = 0
  | counter(a, x::xs) = if a = x then 1+counter(a, xs)
            else counter(a, xs);

fun countList(nil) = []
  | countList(x::xs) =
    (x, counter(x, x::xs))::countList(xs);

val lst = countList([1,2,1,1,3,4,5,2,1,2,1]);

Дает мне значение = [(1,5),(2,3),(1,4),(1,3),(3,1),(4,1),(5,1),(2,2),(1,2),(2,1),(1,1)]: (int * int) список

Что не должно быть проблемой, просто перебрать каждое значение и посмотреть, равны ли первые значения, а затем только дать первое значение, а затем вернуть только наибольшее (ые) значение (а), но я не могу понять эту часть. Я думаю, у меня просто проблемы с циклическим просмотром списка и сравнением с текущим значением, которое я проверяю.

1 ответ

Решение

После того, как вы вычислили lst список, вам не нужно искать соответствующие элементы в нем. Единственное, что вам нужно сделать, - это пройти по списку, чтобы найти элемент с максимальным значением tuple second.

fun findMax l =
  let fun find (nil, acc) = acc
  | find ((value, count)::xs, (acc_value, acc_count)) =
    if count > acc_count then find (xs, (value, count))
    else if value = acc_value then (acc_value, acc_count)
    else find (xs, (acc_value, acc_count))
  in find (l, (0, 0)) end;

findMax lst;
val it = (1, 5): int * int

Однако это решение имеет O (n2) сложность. Кроме того, вы можете отсортировать элементы сначала за O(n * log n), а затем вернуть первый (или несколько) элементов из списка с максимальным количеством вхождений.

Другие вопросы по тегам