2016-10-03 4 views
0

Я уверен, что проблема тривиальна. К сожалению, я новичок в программировании Ocaml, но я, скорее всего, смотрю в неправильном направлении.Сумма наибольших значений

Я хочу создать функцию sum_largest_values, которая принимает n самых больших значений между входами и суммирует их.

Моя лучшая попытка до сих пор:

utop # let sum_largest_values (x:int)(y:int) = 
if (x > y) || (y > x) then ((+) x y) 
else 
0;; 

Проблема встает, когда я пытаюсь добавить третье значение:

utop # let sum_largest_values (x:int)(y:int)(z:int) = 
if (x > y > z) || (y > x > z) then ((+) x y) 
else 
0;; 

Я не могу определить такую ​​функцию:

Error: This expression has type int but an expression was 
expected of type bool 

Почему третье значение z делает функцию непригодной?

+0

разделите и победите! Функциональное программирование поощряет композицию, т. Е. Набирает наибольшую n -> сумму – karakfa

+0

. Я не вижу, как любая версия соответствует вашим требованиям; конечно, если спецификация «суммирует n наибольших значений», то n должно быть параметром для функции, но я ее нигде не вижу.** Начните с получения правильной сигнатуры функции **, прежде чем беспокоиться о теле. Если ваша задача состоит в том, чтобы суммировать n наибольших элементов списка вещей, тогда подпись должна включать * список * и * счетчик *. Получите это право и сделайте метод возвратом * неправильного * значения, и теперь у вас есть что-то, что вы можете по крайней мере начать тестировать, пока вы получите правильное тело. –

+0

Кроме того, почему метод 'sumsqr' вместо' sum_largest_values', если это то, что он делает? –

ответ

1

Если я понять вопрос правильно, вы хотели взять в качестве входных данных два int list и один int аргумента, принимая самое большое n значения из конкатенации двух int lists и суммируя их?

(* first, make an inner function to store running total *) 
let rec sum_largest_inner l n acc = 
    match n with 
     0 -> acc 
    | x -> match l with 
       [] -> 0 
      | h :: t -> sum_largest_inner t (x-1) (h+acc) 

Что эта функция делает, принимает один int list и суммируя первые n значения и сохранения его в acc. Эта внутренняя функция предполагает, что int list уже отсортирован в порядке убывания, поэтому мы хотим убедиться, что вы пройдете в действительном int list.

let sum_largest_values x y n = 
    let z = List.sort compare (x @ y) in 
    sum_largest_inner (List.rev z) n 0 

В этой функции мы добавляем y к x и отсортировать полученный список z в порядке убывания, а затем передать полученный int list к нашей внутренней функции сверху. Эта функция может быть легко изменена, чтобы добавить третье, четвертое и т. Д. Количество списков, которые я оставлю вам в качестве упражнения :)

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

1

Если вы хотите, чтобы непосредственно сравнить 3 или более номеров, вы не можете это сделать так:

# 1<2<3;; 
File "", line 1, characters 4-5: 
Error: This expression has type int but an expression was expected of type bool 

Вы можете строить более сложные условия:

# (1<2) && (2<3);; 
- : bool = true 
# ((1<2) && (2<3)) || ((3<4) && (4<5));; 
- : bool = true 

Но, возвращаясь к исходной задаче

sumsqr, который принимает n самых больших значений между входами и суммирует их

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