2017-11-07 8 views
2

(단어 주파수 "안녕하세요 사람 안녕하세요") 내가이 오류가문자열의 단어 빈도를 반환하는 함수를 작성하십시오. 내 코드의 경우 문자열의 단어 빈도를 반환하는 함수를 작성해야합니다.

: 나는 그것을 같은 입력을 줄 때

(define (num-occurs sym lst) 
    (define (counter sym lst count) 
    (cond ((null? lst) count) 
      ((equal? (car lst) sym) (counter sym (cdr lst) (+ 1 count))) 
      (else (counter sym (cdr lst) count)))) 
    (counter sym lst 0)) 

(define (remove-all elem lst) 
    (if (null? lst) 
     '() 
     (if (equal? elem (car lst)) 
      (remove-all elem (cdr lst)) 
      (cons (car lst) (remove-all elem (cdr lst)))))) 

(define (word-frequencies str) 
    (let ((lst (string->list str))) 
    (if (null? lst) 
     '() 
      (append (list (cons (car lst) (num-occurs (car lst) lst))) 
        (word-frequencies (remove-all (car lst) (cdr lst))))))) 

: 지금까지 나는 다음과 같은 코드가 있습니다. 문자열 -> 목록 : 계약 위반 예상 됨 : 문자열? 주어진 : (공간 \ # 공간 # \ e # \ r # \ e # \ 공간 # \ p # \ e # \ r # \ s # \ o # \ n # \ 공간 # \ i)

도움이 될만한 이유는 무엇입니까? 최종 출력물이 보이길 원합니다.

((안녕하세요. 2) (가. 1) (사람. 1))

+0

문자의 목록을 반환 list' 현악기와>'주의하십시오
우리는 또한 단어 및 주파수의 쌍을 구축하는 기능을 사용할 수있다 기호가 아닙니다. 따라서'(string-> list "hi")'는'(# \ h # \ i)'를 반환합니다. – PieOhPah

+0

문자열에서 목록으로 직접 변환하는 방법을 알고 계십니까? 그래서 그것은 단지 '(hi person hi)가됩니다. –

+0

문자열을 분리하고'string-> symbol'을 결과 문자열 목록, 즉에 매핑 할 수 있습니다. '(map string-> symbol (문자열 분리 "hi there person hi"))'. – assefamaru

답변

1

한 것은 당신이 인터프리터에있는 당신의 가정을 테스트해야한다는 것입니다 :

> (string->list "hi") 
'(#\h #\i) 

string->list 문자의 목록, 문자열이 아닌 목록을 생성합니다.
나중에이 문자 목록에 대해 재귀를 시도하면이 문자가 중단됩니다.

라켓은 많은 유용한 라이브러리 기능을 가지고있다 (string->list 문자열의리스트를 생성 한 경우에도 기능을하기 때문에 깰 것 재귀. 아닌 문자열 목록을 예상), 그리고 당신이 찾고있는 사람은 수행 존재.

string-split은 문자열 (공백)을 문자열 목록으로 나눕니다.

> (string-split "hi there hi") 
'("hi" "there" "hi") 

또한 목록을 목록의 목록으로 그룹화하는 group-by이 있습니다.
(우수 설명서에서이 기능들을 찾으십시오.)
group-by은 그룹화 할 항목이 필요합니다. 문자열 자체를 사용합시다.

> (define id (lambda (x) x)) 
> (group-by id (string-split "hi there hi")) 
'(("hi" "hi") ("there")) 

이것은 매우 유용합니다.

> (define (frequency-pair strings) (cons (car strings) (length strings))) 
> (frequency-pair '("hi" "hi")) 
'("hi" . 2) 
> (map frequency-pair (group-by id (string-split "hi there hi"))) 
'(("hi" . 2) ("there" . 1)) 

가 함께 퍼팅 :

(define (word-frequencies str) 
    (define (id x) x) ; Group strings by their own value 
    (define (frequency-pair strings) (cons (car strings) (length strings))) 
    (map frequency-pair (group-by id (string-split str)))) 

> (word-frequencies " hi hello hi there over there") 
'(("hi" . 2) ("hello" . 1) ("there" . 2) ("over" . 1)) 
0

string->list 기능은 문자의 목록을 반환하기 때문에 오류의 원인이었다. 이 같은 수행하려고한다면 :

(string->list "hi there person hi") 

을 당신은 '(\#h \#i \#space \#t \#h \#e ...) 대신 '(hi there person hi)로 끝날 것입니다.

가장 간단한 방법은 문자 목록을 스캔하고 현재 문자 (car)가 #\space (공백) 일 때를 감지하고이를 기반으로 각 단어 문자열을 작성하여 문자열의 기호 목록을 작성하는 것입니다. 이것은 아마도 가장 효율적인 방법은 아니지만 일을합니다.

(define (string-to-lat str) 
    (let ([char-list (string->list str)]) 
    (let build-list ([s char-list] [l '()] [w ""]) 
     (cond ((null? s) l) 
      ((null? (cdr s)) 
      (append l (list (string->symbol (string-append w (string (car s))))))) 
      (else 
      (if (char=? (car s) #\space) 
       (build-list (cdr s) (append l (list (string->symbol w))) "") 
       (build-list (cdr s) l (string-append w (string (car s)))))))))) 

(string-to-lat "hi there person hi")'(hi there person hi)을 반환합니다.

  1. string->list와 문자의 목록에 문자열로 변환 :

    은 다음 단계입니다.

  2. 초기 유효 범위 변수를 초기 값에 바인딩하는 재귀 함수 build-list을 빌드하십시오. 공간이 있으면
  3. 중요한 부분이
    • 처럼가는 마지막 if 표현에있다 ", 공백없이 문자의 목록 build-list를 호출하고 여기에 w를 추가하여 l을 업데이트하고, 빈 문자열로 w를 재설정.
    • 를하지 않으면 재발 일반적으로 문자열 w(string (car s))를 추가하여.
,536,

w은 각 단어를 빌드하여 기호로 변환하고 s char 목록에 공백이있을 때마다 최종 목록에 넣는 데 도움이되는 단어 누적 기입니다.

이렇게하면 결과 목록에서 각 기호의 발생을 계산하는 것이 간단해야합니다.내가 배운