How to change this function, “car” got problems

微笑、不失礼 提交于 2020-03-03 11:55:08

问题


I want to write a function, which converts from a "normal" notation like this: "1+4*2-8" to this pre-notation: "+1-*428".

I hope you get the point here. Important: It must be in Strings.

What I get so far:

(define (converter lst )
     (let ((operand1 (car lst))
           (operator (car (cdr lst)))
           (operand2 (caddr lst)))
       (list operator
             (converter operand1)
             (converter operand2)))
  )
(infixLst->prefixLst '(1 + 2 * 3))

I got two problems here.

1) It's for Lists, I need it work for Strings like "1+3" and not '(1+3)

2) It doesn't work so far (even not for Lists), because it give me some errors regarding the "car", e.g: car: expects a pair, given 1

Soo starting with the List -> String change: (I know that (list is unappropriate here. As well as the other list-methods but I didnt got a better idea so far.

(define (infix->prefix str)
  (let ((operand1 (car str))
           (operator (cadr str)) 
           (operand2 (caddr str)))
       (list operator
             (infix->prefix operand1)
             (infix->prefix operand2)))
  )

(infix->prefix "1 + 2")

回答1:


The normal notation 1+4*2-8 is called infix notation.

  • If you simply need to use that notation, Racket has a ready module: (require infix), here's a link to its documentation.

  • If you want to practice writing your own infix parser, the shunting-yard algorithm can do that. It uses a stack to keep track of the operators in the math expression.

If you want to parse math from a string, you need to first split the string into a list of tokens (numbers and operators). Start with a math->tokens procedure that simply returns a list of the tokens without caring about their meaning. There are many ways to write it. Here is one:

(define (math->tokens s)
  (let collect-tokens ((i 0) (tokens '()))
    (if (= i (string-length s))
        (reverse tokens)
        (let ((char (string-ref s i)))
          (if (not (char-numeric? char))
              (let ((operator (string->symbol (string char))))
                (collect-tokens (+ i 1) (cons operator tokens)))
              (let collect-number ((j (+ i 1)))
                (if (and (< j (string-length s))
                         (char-numeric? (string-ref s j)))
                    (collect-number (+ j 1))
                    (let ((number (string->number (substring s i j))))
                      (collect-tokens j (cons number tokens))))))))))

For example, (math->tokens "+1-*428") returns the list of tokens (+ 1 - * 428). Now you can apply the shunting-yard algorithm to that list.



来源:https://stackoverflow.com/questions/60021926/how-to-change-this-function-car-got-problems

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!