2016-10-10 17 views
0

방금 ​​하스켈을 배우기 시작했고 하스켈에 루프와 로컬 변수가있는 프로그램을 작성하는 방법을 이해하지 못했습니다. 누구나 그러한 프로그램이 하스켈을 어떻게 보일지 제안 할 수 있습니까? 로컬 변수가 포함되어 있기 때문에 두 번째 사이클을 교체하는 방법은 무엇입니까? 하스켈 코드를 작성하는하스켈 루프와 로컬 변수

#include <iostream> 
using namespace std; 

int main() { 

int n; 
int a [100]; 
cin >> n; 

for (int i = 0; i < n; i ++) { 
    cin >> a[i]; 
} 

int max = 0; 
int index = -1; 

for (int i = 0; i < n - 1; i ++) { 
    if (a[i+1] - a[i] > max) { 
     max = a[i+1] + a[i]; 
     index = i; 
    } 
} 

cout << index << endl; 

return 0; 

} 

내 시도 :

module MyProgram where 

import Data.List 
import Data.Ord 

-- Getting a new modernized list 

f :: Int a => [a] -> [a] 
f x = zipWith (-) (tail x) (x) 

지금 난 그냥 목록을 실행하고 최대의 요소를 찾아 색인을 저장해야합니다. C 및 Java에서 어떻게 수행하는지 이해하고 위에 예제를 제시했다. 어떻게 구현 했는가?하지만 사이클이 없으므로 하스켈에서 구현했다. 재귀가 필요합니까?

필자의 주요 어려움은 하스켈의 설계가 저를 주기적 변수로 대체 할 수 있다는 것을 이해하지 못한다는 사실에 있습니다. 나는 인터넷에 대한 정보를 찾고 있었지만 나에게 이해할만한 것을 찾을 수 없었다.

+0

하스켈 시도를 보여줄 수 있습니까? 그들이 무엇을 시도했는지 이해하면 사람들은 당신을 더 잘 도울 수 있습니다. – Sibi

+0

예, 물론, 코드 – alex

+0

'Int a => [a] -> [a]'가 유효하지 않습니다. 여러분은'Integral a =>'또는'Ord a =>'라고 생각합니다. – ThreeFx

답변

2

우선, 요소 간의 차이점 목록을 얻고 싶습니다. 의 당신의 시도를 살펴 보자 : 우리가 재귀를 사용하는 경우

f x = zipWith (-) (tail x) x 

지금, 우리는이처럼 정의 할 수 있습니다 :

findMax :: [Int] -> Int 
findMax list = helper 0 -1 minusInfinity $ zipWith (-) (tail list) list 
    where 
    helper _   maxIndex _   []   = maxIndex 
    helper currentIndex maxIndex currentMax (elem:list) 
     | elem > currentMax = helper (currentIndex + 1) currentIndex elem list 
     | otherwise = helper (currentIndex + 1) maxIndex currentMax list 
    minusInfinity = minBound :: Int -- the smallest element possible 

그러나 어떻게 든 재귀 오히려 추한 자세한입니다. 우리가 더 잘할 수 있는지 보자 :

f 이미 올바른 빼기 목록을 생성합니다.

이제 각 요소를 색인과 연결하려고합니다. 당신이 고려해야 할 요소가 현재 액세스 할 수있는 튜플의 오른쪽 부분입니다

zip [0..] list = [(0, 1st element), (1, 2nd element), ..] 

snd에 의해 :

snd (index, elem) == elem 

사용 하스켈에서 정보를 결합 쉽게 zip를 사용하여 튜플 (Int, Int) 수행 할 수 있습니다 기능 maximumBy, 우리는 지금 얻을 :

g x = maximumBy (comparing snd) $ zip [0..] $ f x 

maximumBy (comparing snd) 수단 "는 m을 받고 ax 요소는 comparing 각 튜플의 일부분은 snd입니다. " 이제 (index, element) 튜플을 반환합니다. 여기서 element은 최대입니다. 튜플의 첫 번째 요소에 액세스하기 위해 사용할 수 있습니다 위의 순환 식보다 훨씬 더 우아

f x = fst $ maximumBy (comparing snd) $ zip [0..] $ zipWith (-) (tail x) x 

:

fst (index, element) == index 

그래서 전체 기능과 같이 쓸 수있다.

import Data.List 

calc :: (Integral a) => [a] -> a 
calc = snd . foldl (\(max,index) (x,y) -> if (y-x) > max then (y+x,index) else (max,index + 1)) (0,-1) . helper 

helper :: [a] -> [(a,a)] 
helper x = zip (tail x) (init x) 

helper 요소의 연속 쌍의 목록을 구축 :

0

여기에 그것을 할 수있는 또 다른 방법입니다. 그런 다음 calc은 명령 루프에서 비교 및 ​​다른 조작을 수행합니다.accumulator는 로컬 변수 maxindex으로 구성된 튜플입니다. 마지막에 색인 만 필요하기 때문에 snd을 사용하여 해당 부분을 가져옵니다. 우리는 작업을 더 쉽게하기 위해 입력을 튜플로 표현합니다.

Demo