编译原理习题4.4.5

一、拿到该题目的时候按正常思路6个a是是别的了,但是题目给的问题是识别不了。

https://stackoverflow.com/questions/17456994/how-does-backtracking-affect-the-language-recognized-by-a-parser

查看该提问,该提问者也是跟我一样的想法,在递归ASA的时候使用if (!S(str, start+1, end-1)) 的方式进行判断

但是通过递归下降的方式是没有向前看,所以end不应该有减一的操作。

所以正确的编写方式应该如下所示:

int A(const string &a, int start);

int ASA(const string &a, int start) {
    if (start + 2 >= a.length()) {
        return start;
    }

    int next = start;
    if (a[start] == 'a') {
        next = A(a, start + 1);
        if (next == start + 1) {
            return start;
        }
    }
    if (next < a.length() && a[next] == 'a') {
        return next + 1;
    }
    return start;
}

int AA(const string &a, int start) {
    if (start + 2 > a.length()) {
        return start;
    }
    if (a[start] == 'a' && a[start + 1] == 'a') {
        return start + 2;
    }

    return start;
}

int A(const string &a, int start) {
    if (start == a.length()) {
        return start;
    }

    int next = ASA(a, start);
    if (next != start) {
        return next;
    }

    return AA(a, start);
}

int main() {
    cout << A("aaaaaaaaa", 0) << endl;

    system("pause");

    return 0;
}
View Code

 

关于该问题的证明可以看如下的链接

https://www.zhihu.com/question/37746384

 

可以先研究并运行上面贴的代码在各个长度的a所输出的匹配长度再来看上面知乎的链接会比较容易懂,否则很容易对该链接看的云里雾里

 

posted @ 2022-06-29 22:28  LCAC  阅读(114)  评论(0)    收藏  举报