crislanio_macedo Posted March 8, 2015 at 07:22 PM Report Share #578970 Posted March 8, 2015 at 07:22 PM (edited) Olá pessoal queria que dada uma lista e um elemento, retornar todos os índices do elemento em uma lista. para isso tenho algumas funções em partes: TakeUmElemento (t:ts) id | id==0 =t |otherwise =takeUmElemento ts (id-1) -- ------------------------------------------------------------------------- --dMod x = (x `mod` 10) dDiv x =(x `div` 10) inteiroPraLista :: Int -> [int]-- inteiroPraLista x | x<10 = [x] -- error "Entrada invalida" |otherwise= if (dDiv x) >10 then (dMod x):inteiroPraLista (dDiv(x)) else dMod(x):[dDiv (x) ] -- ------------------------------------------------------------------------- indice1 l@(t:ts) e = if e==t then inteiroPraLista(takeUmElemento l e) else indice1 ts e --indice 2 [1,2,3,4,2] = [1,4] Contudo vejo que a função indice1 não está bem como eu queria, me ajudem nessa lógica. em indice1 eu tenho caso o elemento e seja igual ao 1° elemento da lista eu chamaria, a função takeUmElemento l e com a lista e o elemento, ela retornaria o índice do elemento para uma lista, caso o elemento não fosse igual chamaria o restante da função indice1 ts e Mas o resultado está sendo. *Main> indice1 [1,2,3,4,2] 2 [4] *Main> indice1 [1,2,3,4,2] 3 *** Exception: Lista2.hs:(30,1)-(31,40): Non-exhaustive patterns in function takeUmElemento Como eu faria para que a função takeUmElemento l e retornasse um elemento e esse elemento fosse adicionado a inteiroPraLista ? Att, Edited March 8, 2015 at 08:50 PM by pwseo Corrigidas tags code. Link to comment Share on other sites More sharing options...
pwseo Posted March 8, 2015 at 08:23 PM Report Share #578976 Posted March 8, 2015 at 08:23 PM crislanio_macedo, Vou dissecar o teu código passo-a-passo e vamos tentar chegar à solução do teu problema. Tomei a liberdade de reformatar algum do teu código. -- tinhas aqui um erro: 'TakeUmElemento' em vez de 'takeUmElemento' takeUmElemento (t:ts) id | id == 0 = t | otherwise = takeUmElemento ts (id - 1) Qual é o objectivo deste pedaço de código? É essencialmente a função do operador (!!), que é bastante mais claro em termos sintácticos: *Main> "crislanio_macedo" !! 3 's' *Main> takeUmElemento "crislanio_macedo" 3 's' Depois temos este bloco: -- por algum motivo tinhas comentado esta linha erradamente dMod x = x `mod` 10 dDiv x = x `div` 10 inteiroPraLista :: Int -> [int] inteiroPraLista x | x < 10 = [x] -- error "Entrada invalida" | otherwise = if dDiv x > 10 then dMod x : inteiroPraLista (dDiv x) else dMod x : [dDiv x] Sinceramente, não percebi. Qual é o objectivo de inteiroPraLista? Estás a tentar devolver uma lista com os algarismos de um número? Se sim, para que precisas disso e em que ponto do algoritmo entra esse passo? Repara também que alterei o aspecto da tua função; tinhas imensos parênteses bastante mal colocados (é algo que deverás procurar esclarecer, essencial à escrita de código legível em Haskell, e muito diferente das linguagens imperativas mais comuns). Depois chegamos à função indice1 (que limpei substituindo takeUmElement por !!): indice1 l@(t:ts) e = if e == t then inteiroPraLista (l !! e) else indice1 ts e Esta função está completamente dependente da inteiroPraLista, que não faz grande sentido a meu ver. A solução que tenho em mente é bastante mais simples, com apenas meia dúzia de linhas e completamente genérica. Ainda assim, aguardo as tuas respostas, para podermos levar-te à solução de uma forma mais didáctica do que apresentando o código final. 1 Report Link to comment Share on other sites More sharing options...
crislanio_macedo Posted March 8, 2015 at 09:15 PM Author Report Share #578980 Posted March 8, 2015 at 09:15 PM crislanio_macedo, Vou dissecar o teu código passo-a-passo e vamos tentar chegar à solução do teu problema. Tomei a liberdade de reformatar algum do teu código. -- tinhas aqui um erro: 'TakeUmElemento' em vez de 'takeUmElemento' takeUmElemento (t:ts) id | id == 0 = t | otherwise = takeUmElemento ts (id - 1) Qual é o objectivo deste pedaço de código? É essencialmente a função do operador (!!), que é bastante mais claro em termos sintácticos: *Main> "crislanio_macedo" !! 3 's' *Main> takeUmElemento "crislanio_macedo" 3 's' Depois temos este bloco: -- por algum motivo tinhas comentado esta linha erradamente dMod x = x `mod` 10 dDiv x = x `div` 10 inteiroPraLista :: Int -> [int] inteiroPraLista x | x < 10 = [x] -- error "Entrada invalida" | otherwise = if dDiv x > 10 then dMod x : inteiroPraLista (dDiv x) else dMod x : [dDiv x] Sinceramente, não percebi. Qual é o objectivo de inteiroPraLista? Estás a tentar devolver uma lista com os algarismos de um número? Se sim, para que precisas disso e em que ponto do algoritmo entra esse passo? Repara também que alterei o aspecto da tua função; tinhas imensos parênteses bastante mal colocados (é algo que deverás procurar esclarecer, essencial à escrita de código legível em Haskell, e muito diferente das linguagens imperativas mais comuns). Depois chegamos à função indice1 (que limpei substituindo takeUmElement por !!): indice1 l@(t:ts) e = if e == t then inteiroPraLista (l !! e) else indice1 ts e Esta função está completamente dependente da inteiroPraLista, que não faz grande sentido a meu ver. A solução que tenho em mente é bastante mais simples, com apenas meia dúzia de linhas e completamente genérica. Ainda assim, aguardo as tuas respostas, para podermos levar-te à solução de uma forma mais didáctica do que apresentando o código final. Mais uma vez muito útil e simples suas explicações. Grato. Bom, a minha ideia ao usar a função inteiroPraLista seria a medida que eu pegasse o índice do elemento da lista eu adicionasse a lista. Tentarei proceder aqui com minha resolução, mas como vossa excelentíssima pessoa está a perceber eu estou a ter dificuldades em ilustrar minhas ideias na linguagem (sintaxe). Tentarei aqui proceder com minha resolução para que possa arguir-me das minhas premissas. Link to comment Share on other sites More sharing options...
crislanio_macedo Posted March 8, 2015 at 09:30 PM Author Report Share #578981 Posted March 8, 2015 at 09:30 PM (edited) indices :: Eq a=> a ->[a] -> [int] indices x ys = [i | (i,y) <-zip [0..n] ys, x==y] where n =length ys -1 Queria fazer algo diferente disso, algo não recursivo. Como então fazer uma função para retornar o índice da função e não o valor e então adiciona-la a uma lista. Edited March 8, 2015 at 09:27 PM by crislanio_macedo Link to comment Share on other sites More sharing options...
crislanio_macedo Posted March 8, 2015 at 09:55 PM Author Report Share #578983 Posted March 8, 2015 at 09:55 PM (edited) indice1 (t:ts) e = if e == t then e:indice1 ts e else indice1 ts e Eu precisaria de uma função para pegar os índices e só então adicionar a lista. Teria alguma função que faça isso em algum módulo? indice1 (t:ts) e = if e == t then Data.List.findIndices indice1 ts e else indice1 ts e Não estou nem a saber como usá-la Edited March 8, 2015 at 10:12 PM by crislanio_macedo Link to comment Share on other sites More sharing options...
pwseo Posted March 8, 2015 at 10:29 PM Report Share #578984 Posted March 8, 2015 at 10:29 PM indices :: Eq a=> a ->[a] -> [int] indices x ys = [i | (i,y) <-zip [0..n] ys, x==y] where n =length ys -1 Queria fazer algo diferente disso, algo não recursivo. Por que motivo pretendes algo diferente? Além disso, essa solução não tem recursividade explícita e é perfeitamente válida e muito compacta. 1 Report Link to comment Share on other sites More sharing options...
crislanio_macedo Posted March 8, 2015 at 11:33 PM Author Report Share #578988 Posted March 8, 2015 at 11:33 PM É por que esta solução não é minha. Queria usá-la para construir uma um pouco diferente, por exemplo sem listas de compreensão. Link to comment Share on other sites More sharing options...
pwseo Posted March 8, 2015 at 11:49 PM Report Share #578991 Posted March 8, 2015 at 11:49 PM Percebo. Vou dar-te uma sugestão então, e depois vamos refinando a função até ficar mais simples de utilizar. Para fazeres o que pretendes, precisas de uma função recursiva que mantenha registo de várias coisas: O elemento que procuras A lista onde procuras o elemento A posição em que vais Uma lista de posições onde já foi encontrado o elemento Vou escrever o caso de base e tu vais tentar completar a função: pos :: (Eq a, Num b) => a -- o elemento que procuramos -> [a] -- a lista onde o procuramos -> b -- a posição em que vamos -> [b] -- a lista de posições onde já encontrámos o elemento -- caso base: pos _ [] _ indices = indices -- quando a lista onde procuramos acabar, devolver a lista de posições que acumulámos. pos e (x:xs) i is = -- agora completa tu aqui. É suposto que aconteça o seguinte: *Main> pos 2 [1,2,3,4,2] 0 [] [1,4] Não te preocupes com os dois argumentos adicionais que passámos à pos. Eventualmente irão desaparecer; estão ali para te ajudar a perceber o funcionamento. 1 Report Link to comment Share on other sites More sharing options...
crislanio_macedo Posted March 9, 2015 at 12:37 AM Author Report Share #578994 Posted March 9, 2015 at 12:37 AM (edited) Somente um detalhe a ser corrigido . Prelude> :l Lista2.hs [1 of 1] Compiling Main ( Lista2.hs, interpreted ) Ok, modules loaded: Main. *Main> :t pos pos :: (Eq a, Num a1) => a -> [a] -> a1 -> [a1] -> [a1] *Main> pos 2 [1,2,3,4,2] 0 [] [1,3] pos _ [] _ indices = indices -- quando a lista onde procuramos acabar, devolver a lista de posições que acumulámos. pos e (x:xs) i is = if e ==x then i:pos e xs i is else pos e xs (i+1) is -- agora completa tu aqui. pos _ [] _ indices = indices -- quando a lista onde procuramos acabar, devolver a lista de posições que acumulámos. pos e (x:xs) i is = if e ==x then i:pos e xs (i+1) is else pos e xs (i+1) is -- agora completa tu aqui. --------------------- *Main> :r [1 of 1] Compiling Main ( Lista2.hs, interpreted ) Ok, modules loaded: Main. *Main> pos 2 [1,2,3,4,2] 0 [] [1,4] *Main> Muitas vezes se precisa auxiliar uma pessoa mesmo que esteja a resposta óbvia mas a pessoa não consiga enxergá-la. Obrigado por me auxiliar , guiar meu raciocínio passo a passo. Grato !! Edited March 9, 2015 at 12:38 AM by crislanio_macedo Link to comment Share on other sites More sharing options...
pwseo Posted March 9, 2015 at 12:41 AM Report Share #578995 Posted March 9, 2015 at 12:41 AM Ainda bem que consegui ajudar 🙂 Agora falta o passo final: remover os argumentos adicionais. indices :: (Eq a, Num b) => a -> [a] -> [b] indices x xs = pos x xs 0 [] Próximo passo (opcional): integrares a função pos na função indices (podes colocá-la dentro de uma cláusula where). Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now