• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

R4K4T4

Devolve os números de uma lista que são superiores à média da mesma

15 mensagens neste tópico

Fiz este código para um exercício da disciplina de programação funcional. Pode ajudar alguns.

Vejam:

module Media where

media :: [Float] -> Float
media [] = 0
media (x:xs) = sum(x:xs)/fromIntegral(length(x:xs))

supmedia :: [Float] -> [Float]
supmedia [] = []
supmedia (x:xs) |x>media(x:xs) = x:supmedia xs -- é uma função recursiva
                |otherwise = supmedia xs

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isso não vai funcionar, porque para cada posição, só consideras a média dos elementos a partir daquela posição, i.e., quando vais tratar o segundo elemento, já deitaste fora o primeiro, e assim esse valor não contará para a média.

Isso está mesmo a pedir um filter.

Da forma como tens, devias primeiro calcular a média, e só depois ter a tua função, que usava a média previamente calculada (em vez de a calculares em cada chamada recursiva).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Isso não vai funcionar, porque para cada posição, só consideras a média dos elementos a partir daquela posição, i.e., quando vais tratar o segundo elemento, já deitaste fora o primeiro, e assim esse valor não contará para a média.

Isso está mesmo a pedir um filter.

Da forma como tens, devias primeiro calcular a média, e só depois ter a tua função, que usava a média previamente calculada (em vez de a calculares em cada chamada recursiva).

Estás errado. Ele compara a média da lista introduzida inicialmente ao valor em questão.

E mais pode-se resolver sem filters

Deve bastar só mais um ajuste para essa função estar certa :P

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Estás errado. Ele compara a média da lista introduzida inicialmente ao valor em questão.

E mais pode-se resolver sem filters

Deve bastar só mais um ajuste para essa função estar certa :P

Não, não estou errado.

Introduz a lista [1,2,3,4] (ou qualquer outra crescente), e vais ver que o resultado é uma lista vazia. Porquê? Porque 1 não é maior do que a média de [1,2,3,4], 2 não é maior do que a média [2,3,4], 3 não é maior do que a média de [3,4], e 4 não é maior do que a média de [4]. Devia comparar 2 com a média de [1,2,3,4] e não com a média de [2,3,4], ...

Sim, pode-se resolver sem o filter, e já disse no meu post anterior como.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A função media pode ser melhorada para percorrer a lista apenas 1 vez:

media :: [Float] -> Float
media [] = 0
media (x:xs) = mediaAC (0,0) (x:xs)
where mediaAC ac [] = (snd ac)/(fst ac)
      mediaAC (n,s) (h:t) = mediaAC (n+1,s+h) t	

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

A função media pode ser melhorada para percorrer a lista apenas 1 vez:

media :: [Float] -> Float
media [] = 0
media (x:xs) = mediaAC (0,0) (x:xs)
where mediaAC ac [] = (snd ac)/(fst ac)
      mediaAC (n,s) (h:t) = mediaAC (n+1,s+h) t	

Isso não se aplica aqui.

Sim, pode-se resolver sem o filter, e já disse no meu post anterior como.

Podias-me dar outra "luz". Não estou a conseguir :S

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Podias-me dar outra "luz". Não estou a conseguir :S

Passa o cálculo da média para fora da função supmedia.

Depois na função supmedia passas a usar um valor previamente calculado (ou seja, acrescenta um argumento à função  supmedia, que é a média).

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

O melhor mesmo é meteres aqui o código. Estou as cegas. Da minha turma ninguém consegui fazer isso :S

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

supmedia1 :: [Float] -> [Float]
supmedia1 l = supmediaAC l [] (media l)
where supmediaAC [] lf _ = lf
      supmediaAC (x:xs) lf m | x > m = ( x (supmedia xs)
			     | otherwise = supmedia xs

Neste caso usei um acumulador para gerar a lista final. Como vês, logo no início calculo a média da lista inicial, e depois basta chamar a função auxiliar com esse parâmetro.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

supmedia1 :: [Float] -> [Float]
supmedia1 l = supmediaAC l [] (media l)
where supmediaAC [] lf _ = lf
      supmediaAC (x:xs) lf m | x > m = ( x (supmedia xs)
			     | otherwise = supmedia xs

Neste caso usei um acumulador para gerar a lista final. Como vês, logo no início calculo a média da lista inicial, e depois basta chamar a função auxiliar com esse parâmetro.

Adicionei a função media a esse texto e interpretei e nao dá.

Deixa o código pronto a compilar só mesmo para testar, se faz favor.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Peço desculpa, enganei-me aí ao chamar a função recursiva, escrevi "supmedia" em vez de "supmedia1" e ele executou a minha "supmedia" definida com filter.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

supmedia1 :: [Float] -> [Float]
supmedia1 l = supmediaAC l [] (media l)
where supmediaAC [] lf _ = lf
      supmediaAC (x:xs) lf m | x > m = ( x (supmedia xs)
			     | otherwise = supmedia xs

Neste caso usei um acumulador para gerar a lista final. Como vês, logo no início calculo a média da lista inicial, e depois basta chamar a função auxiliar com esse parâmetro.

Penso que devias estar a usar a supmediaAC na recursividade, em vez da supmedia.

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Penso que devias estar a usar a supmediaAC na recursividade, em vez da supmedia.

Tens razão, foi esse o erro. Fica aqui então o código:

supmedia1 :: [Float] -> [Float]
supmedia1 l = supmediaAC l [] (media l)
where supmediaAC [] lf _ = lf
      supmediaAC (x:xs) lf m | x > m = ( x (supmediaAC xs lf m)
			     | otherwise = supmediaAC xs lf m

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora