0

定义一个过程 encrypt,它采用三个字符串:要加密的消息和两个字母,我们将其称为常规和加密。字母字符串的长度相同,并且不包含重复项。对于消息中的每个字符,常规查找,如果找到,将其转换为相应位置的加密字符。例如,如果正则为 abc,加密为 def,这意味着消息中的 a 将编码为 ad,ab 编码为 e,ac 编码为 f。

我写了我的代码如下:

(define encrypt
  (lambda (message regular encrypted)
    (define help
      (lambda (ls1 ls2 ls3)
         (if (null? ls1) '()
           (if (and (null? ls2) (null? ls3)) ls1
              (if (equal? (car ls1) (car ls2)) 
                  (cons (car ls3) (help (cdr ls1) ls2 ls3))
                  (help ls1 (cdr ls2) (cdr ls3))))))
    (list->string (help 
                    (string->list message) 
                    (string->list regular) 
                    (string->list encrypted)))))

我一直在尝试跑步。但结果返回Exception in car: () is not a pair

我相当检查它很多次,但我没有我应该改变什么。有没有人可以帮助我?

4

3 回答 3

3

Óscar López 的回答指出了您在此代码中可能遇到的一些问题,但我认为专门解决您提到的错误消息很重要:() is not a pair. 这意味着您正在调用一个需要一对的函数(因此典型的候选人将carcdr一个空列表中。让我们看看您的代码,看看这可能发生在哪里:

(define help
      (lambda (ls1 ls2 ls3)
         (if (null? ls1) '()                                 ; a
           (if (and (null? ls2) (null? ls3)) ls1             ; b
              (if (equal? (car ls1) (car ls2))               ; c
                  (cons (car ls3) (help (cdr ls1) ls2 ls3))  ; d 
                  (help ls1 (cdr ls2) (cdr ls3))))))         ; e
  1. a并且b不要调用任何期望成对的函数,所以你不应该在那里遇到这个问题。
  2. 在行c中,你做(car ls1)(car ls2)。Linea确保ls1is 不是(),但ls2仍然可能是,因为只b检查了不是两者 都是ls2; 任何一个仍然可以。ls3()
  3. 在行d中,您有(car ls3)(cdr ls1)。Linea确保ls1is not (),但ls2仍可能出于与前一个案例中给出的相同原因。
  4. Linee(cdr ls2)(cdr ls3),这两者都可能导致问题,因为其中任何一个(但不是两者)都可能是()

虽然你的标题没有说出来,但你的问题提到这实际上发生在car,这意味着它没有发生在e,留下cand d。它要么发生在(car ls2)inc(car ls3)in d

如果您使用 Dr. Racket 运行代码,IDE 应该突出显示错误调用发生的位置(类似于此答案中的屏幕截图中显示的内容)。

于 2013-10-31T03:06:10.263 回答
2

help功能并没有像您想象的那样,您实际上需要两个助手:

  • 一个用于迭代消息并“加密”其中的每个字符,因为它使用下一个函数作为助手
  • 还有一个用于“加密”单个字符,负责查找与明文字符相对应的加密字符

如果您不执行上述操作,您会发现并非所有字符都被替换,因为您只遍历常规/加密列表一次,但是要使算法正常工作,您必须为每个字符遍历一次在输入消息中。

于 2013-10-31T01:57:58.883 回答
0
(define (encrypt message regular encrypted)
   (letrec ((key 
              (lambda (reg enc)
                 (if (null? reg) 
                     '()
                     (cons (cons (car reg) (car enc)) 
                           (key  (cdr reg) (cdr enc))))))
             (keys (key (string->list regular) 
                        (string->list encrypted))))
    (list->string
      (let loop ((message (string->list message)))
         (if (null? message) 
             '()
              (cons (cdr (assoc (car message) keys)) 
                    (loop (cdr message))))))))
于 2013-10-31T03:18:05.970 回答