编译原理习题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 @   LCAC  阅读(73)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示