【问题标题】:Racket - Using Two Lists and Outputing StringRacket - 使用两个列表并输出字符串
【发布时间】:2015-02-16 02:37:30
【问题描述】:

作为参考,我在DrRacket 中编程Racket

我使用的“语言”是Intermediate Student with lambda

也就是说,我应该注意这些没有使用高阶函数或 lambda

我正在编写一个名为winner-by-all 的函数,它使用候选人列表和投票列表,并返回获胜者的姓名(得票最多的人)。

我可以让它输出最大的数字,但不是获胜者本身的名字(字符串)。

这是我的winner-by-all 函数,不正确:

;; Signature: winner-by-all: list-of-candidates list-of-votes -> string
;; Purpose: Consumes a list of candidates and a list of votes, and returns 
;;          the name of the winner by the winner-takes-all strategy.
;; Tests:
(check-expect (winner-by-all empty empty) empty)
(check-expect (winner-by-all listofCandidates listofVotes) "Blake")
;; Define:
(define (winner-by-all aloc alov)
  (cond
    [(empty? aloc) empty]
    [else (voting-tally-candidate (max (voting-tally-numVotes (first (tally-by-all listofCandidates listofVotes)))))]
    )
  )

运行时,我收到一条错误消息:

voting-tally-candidate: expects a voting-tally, given 3

所以我的函数更有意义,下面是我的代码的其他一些部分来填补空白:

tally-by:

;; Signature: tally-by: (helper function) list-of-candidates list-of-votes -> list-of-Voting-Tallies
;; Purpose: Consumes a helper function, a list of candidate names, and a list of
;;          votes and produces a list of voting-tallies.
;; Define:
(define (tally-by helper aloc alov)
  (cond
    [(empty? aloc) empty]
    [else (cons (make-voting-tally (first aloc) 
                                   (helper (first aloc) alov))
                (tally-by helper (rest aloc) alov))]
    )
  )

tally-by-all:

;; Signature: tally-by-all: list-of-candidates list-of-votes -> list-of-Voting-Tallies
;; Purpose: Consumes a list of candidate names and a list of votes and produces a
;;          list of voting-tallies.
;;          (Winner-Takes-All strategy).
;; Tests:
(check-expect (tally-by-all empty empty) empty)
(check-expect (tally-by-all listofCandidates listofVotes) (cons (make-voting-tally "Blake" 3)
                                                          (cons (make-voting-tally "Ash" 0)
                                                          (cons (make-voting-tally "Bob" 0)
                                                          (cons (make-voting-tally "Will" 0)
                                                          (cons (make-voting-tally "Joey" 0) empty))))))
;; Define:
(define (tally-by-all aloc alov)
  (tally-by top-votes-for aloc alov))

listofVotes:

;; Data Definition
(define-struct vote (choice1 choice2 choice3))
;; A vote is a structure: (make-vote String String String). 
;; interp. 3 candidates that one person has voted for (String).

(define vote1
  (make-vote "Blake" "Joey" "Will"))

(define vote2
  (make-vote "Blake" "Bob" "Ash"))

(define vote3
  (make-vote "Blake" "Ash" "Blake"))

(define listofVotes
  (list vote1 vote2 vote3))

top-votes-for:

;; Signature: top-votes-for: string list-of-strings -> number
;; Purpose: Consumes a name and a list of votes and produces the number of
;;          times that the given name was the first choice vote in the list of votes.
;;          (This tallies points under winner-takes-all strategy.)
;; Tests:
(check-expect (top-votes-for "Blake" empty) 0)
(check-expect (top-votes-for "Blake" listofVotes) 3)
(check-expect (top-votes-for "Bob" listofVotes) 0)
(check-expect (top-votes-for "Ash" listofVotes) 0)
(check-expect (top-votes-for "Joey" listofVotes) 0)
(check-expect (top-votes-for "Will" listofVotes) 0)
;; Define:
(define (top-votes-for cand alov)
  (cond
    [(empty? alov) 0]
    [(string=? (vote-choice1 (first alov)) cand) (+ 1 (top-votes-for cand (rest alov)))]
    [else (top-votes-for cand (rest alov))]
    )
  )

listofCandidates:

(define listofCandidates
  (list "Blake" "Ash" "Bob" "Will" "Joey"))

voting-tally结构:

;; Data Definition
(define-struct voting-tally (candidate numVotes))
;; A voting-tally is a structure: (make-voting-tally String Number). 
;; interp. a candidate (String) and how many votes said
;;         candidate has gotten (Number).

我希望有人能够在 winner-by-all 函数定义方面为我提供帮助,因为我不确定如何使其按预期方式工作。

【问题讨论】:

    标签: string list racket


    【解决方案1】:

    Intermediate student with lambda中可以使用argmax等高阶函数:

    (define (winner-by-all aloc alov)
      (cond
        [(empty? aloc) empty]
        [else (voting-tally-candidate (argmax voting-tally-numVotes
                                              (tally-by-all listofCandidates listofVotes)))]
        )
      )
    

    如果您确实需要在没有高阶函数和 lambda 表达式的情况下实现它,您可以使用自己的函数模拟 argmax,该函数递归迭代 tally-by-all 的所有结果并选择具有最高数量的投票计数投票。

    (define (best-candidate left-candidates best)
      (if (null? left-candidates)
          best
          (let ([fst (car left-candidates)])
            (if (or (null? best)
                    (> (voting-tally-numVotes fst) (voting-tally-numVotes best)))
                (best-candidate (cdr left-candidates) fst)
                (best-candidate (cdr left-candidates) best)))))
    

    然后使用best-candidate 代替argmax 来完成这项工作:

    (define (winner-by-all aloc alov)
      (cond
        [(empty? aloc) empty]
        [else (voting-tally-candidate (best-candidate (tally-by-all listofCandidates listofVotes) null))]
        )
      )
    

    【讨论】:

    • 谢谢!然而,一个问题。在best-candidate 中,left-candidatesbest 等同于什么?就像我必须在定义窗口下方的窗口中输入什么(忘记名称)来测试函数best-candidate
    • (best-candidate (tally-by-all listofCandidates listofVotes) null)。第一个参数 (left-candidates) 是 voting-tally 结构的列表,第二个参数 (best) 是一个累加器,代表迄今为止发现的最佳 voting-tally(第一次调用时为 null)。
    猜你喜欢
    • 2017-09-11
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    • 2014-12-19
    • 1970-01-01
    相关资源
    最近更新 更多