首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Racket/Scheme中将文本解析为树

在Racket/Scheme中将文本解析为树
EN

Stack Overflow用户
提问于 2018-12-25 16:59:18
回答 1查看 667关注 0票数 1

我试图将我的C++代码转换成球拍,因为我正在学习球拍。我的简化C++代码是:

代码语言:javascript
复制
struct Node
{
    char value = '\0';
    std::vector<Node> kids;
    explicit Node(char ch) : value(ch) {}
};

void ParseTree(const std::string& tokens, size_t& i, Node& root)
{
    while (i < tokens.size())
    {
        const Token& token = tokens[i++];
        if (token == '<')   // children begin
        {
            ParseTree(tokens, i, root.kids.back());
        }
        else if (token == '>')  // children end, go up
        {
            return;
        }
        else
        {
            root.kids.emplace_back(token);
        }
    }
}

Node ParseTree(const std::string& s)
{
    size_t i = 0;
    Node root('$');
    ParseTree(Parse(s), i, root);
    return root;
}

非常简单的代码。我对球拍的翻译是:

代码语言:javascript
复制
(define (parse-tree tokens)
    (if(empty? tokens)
       '()
       (cond
         [(eq? '< (car tokens))
           (list (parse-tree (cdr tokens)))]
         [(eq? '> (car tokens))
          (parse-tree (cdr tokens))]    ; no return, how to step up?
         [else
          (cons (car tokens)(parse-tree (cdr tokens)))])))

这里的问题是,我不会返回(eq?'> (car令牌)),所以新的节点被添加到底部.小小的考验:

代码语言:javascript
复制
(parse-tree '(1 < 2 < 3 4 > > Z < X >))

应:

代码语言:javascript
复制
'(1 (2 (3 4)) Z (X))

它是:

代码语言:javascript
复制
'(1 (2 (3 4 Z (X))))

怎么修呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-25 21:04:51

原始方法的问题在于,您试图直接移植一个命令式解决方案,该解决方案甚至使用逐个引用来跟踪遍历的状态。这是行不通的,第一步是用函数编程的方式重新考虑解决方案。

在这些问题中,我们必须跟踪嵌套结构中的位置,最好使用堆栈数据结构来解决。我将使用list来实现一个列表堆栈,下面的助手用于在最上面的列表中追加一个新元素:

代码语言:javascript
复制
(define (append-top ele stack)
  (cons (append (car stack) (list ele))
        (cdr stack)))

现在是实际的解决方案。假设输入列表格式良好,具有相同数量的<>,并且顺序正确(不执行错误检查):

代码语言:javascript
复制
(define (parse-tree tokens)
  (let parse ([tokens tokens] [stack '(())])
    (cond [(null? tokens)
           ; solution is at the top of the stack, return it
           (car stack)]
          [(eq? (car tokens) '<)
           ; start new sublist at the top of the stack
           (parse (cdr tokens) (cons '() stack))]
          [(eq? (car tokens) '>)
           ; pop top element of the stack, append it to previous
           ; frame, continue with solution where we left it
           (parse (cdr tokens) (append-top (car stack) (cdr stack)))]
          [else
           ; add current element to top of stack
           (parse (cdr tokens) (append-top (car tokens) stack))])))

它像预期的那样工作!

代码语言:javascript
复制
(parse-tree '(1 < 2 < 3 4 > > Z < X >))
=> '(1 (2 (3 4)) Z (X))
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53924157

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档