문제

문자열에서 반복 된 단어를 보여주는 함수를 작성하고 발생 순서대로 문자열 목록을 반환하고 비자 레터를 무시할 수 있어야합니다.

EG Hugs Prompt

repetitions :: String -> [String]

repetitions > "My bag is is action packed packed."
output> ["is","packed"]
repetitions > "My name  name name is Sean ."
output> ["name","name"]
repetitions > "Ade is into into technical drawing drawing ."
output> ["into","drawing"]
도움이 되었습니까?

해결책

문자열을 단어로 나누려면 사용하십시오 words 기능 (Prelude에서). 비 단어 문자를 제거하려면 filter ~와 함께 Data.Char.isAlphaNum. 인접한 쌍을 얻기 위해 꼬리와 함께 목록을 지퍼 (x, y). 목록을 접고, 모든 것을 포함하는 새 목록을 고려하십시오. x 어디 x == y.

좋아요 :

repetitions s = map fst . filter (uncurry (==)) . zip l $ tail l
  where l = map (filter isAlphaNum) (words s)

나는 그것이 작동하는지 확실하지 않지만 거친 아이디어를 제공해야합니다.

다른 팁

나는이 언어를 처음 접했기 때문에 내 해결책은 Haskell 베테랑의 눈에 일종의 못 생겼을 수 있지만 어쨌든 :

let repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (words (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') ||  c==' ') x)))))

이 부분은 문자열에서 모든 비 문자와 비 공간을 제거합니다. 에스:

filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') ||  c==' ') s

이것은 문자열을 나눌 것입니다 에스 단어와 그룹에 동일한 단어를 목록에 반환하는 목록 목록을 작성합니다.

List.group (words s)

이 부분이 두 가지 미만의 요소로 모든 목록을 제거하면 다음과 같습니다.

filter (\x -> (length x) > 1) s

우리는 모든 목록을 하나의 요소를 하나의 요소로 하나로 연결하는 것과 관련이 있습니다.

concat (map tail s)

이것은 불가피 할 수 있지만 개념적으로 매우 간단합니다. 예제와 같은 연속적인 중복 단어를 찾고 있다고 가정합니다.

-- a wrapper that allows you to give the input as a String
repititions :: String -> [String]
repititions s = repititionsLogic (words s)
-- dose the real work 
repititionsLogic :: [String] -> [String]
repititionsLogic [] = []
repititionsLogic [a] = []
repititionsLogic (a:as) 
    | ((==) a (head as)) = a : repititionsLogic as
    | otherwise = repititionsLogic as

Alexander Prokofyev가 대답 한 내용을 바탕으로 :

repetitions x = concat (map tail (filter (\x -> (length x) > 1) (List.group (word (filter (\c -> (c >= 'a' && c <= 'z') || (c>='A' && c <= 'Z') || c==' ') x)))))

불필요한 괄호 제거 :

repetitions x = concat (map tail (filter (\x -> length x > 1) (List.group (word (filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x)))))

더 많은 괄호를 제거하려면 $를 사용하십시오 (결말 괄호가 표현의 끝에있는 경우 각 $는 개방 괄호를 대체 할 수 있습니다) : :

repetitions x = concat $ map tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> c >= 'a' && c <= 'z' || c>='A' && c <= 'Z' || c==' ') x

문자 범위를 data.char, merge concat 및 map의 함수로 바꾸십시오.

repetitions x = concatMap tail $ filter (\x -> length x > 1) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

섹션을 사용하고 점이없는 스타일로 카레를 사용하여 단순화하십시오. (\x -> length x > 1) to ((>1) . length). 이것은 결합됩니다 length (> 1) (부분적으로 적용된 연산자 또는 부분) 오른쪽에서 왼쪽 파이프 라인에서.

repetitions x = concatMap tail $ filter ((>1) . length) $ List.group $ word $ filter (\c -> isAlpha c || isSeparator c) x

명시 적 "x"변수를 제거하여 전체 표현식을 포인트로 만들 수 있습니다.

repetitions = concatMap tail . filter ((>1) . length) . List.group . word . filter (\c -> isAlpha c || isSeparator c)

이제 오른쪽에서 왼쪽으로 읽는 전체 기능은 알파 또는 분리기 문자 만 필터링하고, 단어로 분할하고, 그룹으로 나누고, 그룹을 하나 이상의 요소로 필터링 한 다음 나머지 그룹을 첫 번째로 줄이는 파이프 라인입니다. 각각의 요소.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top