题目描述
请你判断,哪些是合法的浮点数
浮点数的表示通常有以下两种形式:
1) 十进制小数形式。由数字和小数点组成,必须有小数点,允许出现若干个前导零。例如(123.)(123.0)(.123)(00123.456)。
2) 指数形式。字母 e(或 E)之前必须有数字,允许出现若干个前导零,e 后面的指数必须为整数。例如(123e3)(00123e4)。
样例
样例输入: 8 1.234 +1.234 -12.3e+23 .2E34 E2 2.3e2.3 2e 001.1 样例输出: Yes Yes Yes No No No No Yes
分析
解法1 正则表达式
使用C++ regex 库可以实现
但问题是C++编译正则表达式的速度实在不快,实用性不高。
此题想正则表达式的时间和用DFA做实际上差不多。DFA(maybe)
解法2 DFA
看起来复杂 实际上很容易归纳
C++14 REQUIRED
#include <bits/stdc++.h>
using namespace std;
struct Node {
    function<bool(string::iterator)> check;
    size_t limit;
    vector<shared_ptr<Node>> next;
    Node(auto a, auto b): check(a), limit(b) {};
    bool exec(auto it) {
        for (size_t c = 0; check(it) && c < limit; ++c, ++it);
        if (next.size() == 0) return true;
        for (auto e : next) {
            if (e->check(it) && e->exec(it)) return true;
        }
        return false;
    }
    // auto attatch(initializer_list<shared_ptr<Node>> ns) {
    //     for (auto&& e : ns) next.push_back(e);
    // }
    template <typename ...Args>
    auto attatch(Args&& ...args) {
        for (auto&& ele : {args...}) next.push_back(ele);
    }
};
auto st = make_shared<Node>([](auto it) {return false;}, -1);
auto n1 = make_shared<Node>([](auto it) {return *it == '+' || *it == '-';}, 1);
auto n2 = make_shared<Node>([](auto it) {return *it == '+' || *it == '-';}, 1);
auto i1 = make_shared<Node>([](auto it) {return isdigit(*it);}, -1);
auto i2 = make_shared<Node>([](auto it) {return isdigit(*it);}, -1);
auto i3 = make_shared<Node>([](auto it) {return isdigit(*it);}, -1);
auto d1 = make_shared<Node>([](auto it) {return *it == '.';}, 1);
auto d2 = make_shared<Node>([](auto it) {return *it == '.';}, 1);
auto ee = make_shared<Node>([](auto it) {return *it == 'e' || *it == 'E';}, 1);
auto ed = make_shared<Node>([](auto it) {return *it == 0;}, -1);
void init() {
    st->attatch(n1, d2, i1);
    i1->attatch(ee, d1);
    d1->attatch(ed, ee, i2);
    d2->attatch(ed, ee, i2);
    i2->attatch(ed, ee);
    ee->attatch(i3, n2);
    n1->attatch(d2, i1);
    d2->attatch(i2);
    n2->attatch(i3);
    i3->attatch(ed);
}
int main() {
    init();
    string s;
    int i;
    while (cin >> i) {
        while (i--) {
            cin >> s;
            cout << (st->exec(s.begin()) ? "Yes" : "No") << endl;
        }
    };
    return 0;
}
很久之后的更新:
此题,我实际上是而为了用智能指针而用智能指针,花费了很多无用的努力,但是过程中也学到了很多东西。
这里使用 shared_ptr 实际上没有必要,而且如果自动机不是一个DAG的话,会出现内存泄露的问题。
智能指针是用来更智能地去管理动态分配内存的工具,用来处理引用关系或者指向的话实际上没有什么优势。使用裸指针也是可以的。
此代码为第二版本。第四版本已经解决上述问题,如下:
#include <bits/stdc++.h>
using namespace std;
struct Node {
    function<bool(string::iterator)> check;
    size_t limit;
    vector<Node*> next;
    Node(auto a, auto b): check(a), limit(b) {};
    bool exec(auto it) const {
        for (size_t c = 0; check(it) && c < limit; ++c, ++it);
        if (next.size() == 0) return true;
        for (auto e : next) {
            if (e->check(it) && e->exec(it)) return true;
        }
        return false;
    }
    void attatch() {}
        
    template <class T, class ...Args>
    void attatch(T&& head, Args&&... args) {
        next.push_back(&head);
        attatch(args...);
    }
};
Node st([](auto it) {return false;}, -1);
Node n1([](auto it) {return *it == '+' || *it == '-';}, 1);
Node n2([](auto it) {return *it == '+' || *it == '-';}, 1);
Node i1([](auto it) {return isdigit(*it);}, -1);
Node i2([](auto it) {return isdigit(*it);}, -1);
Node i3([](auto it) {return isdigit(*it);}, -1);
Node d1([](auto it) {return *it == '.';}, 1);
Node d2([](auto it) {return *it == '.';}, 1);
Node ee([](auto it) {return *it == 'e' || *it == 'E';}, 1);
Node ed([](auto it) {return *it == 0;}, -1);
void init() {
    st.attatch(n1, d2, i1);
    i1.attatch(ee, d1);
    d1.attatch(ed, ee, i2);
    i2.attatch(ed, ee);
    ee.attatch(i3, n2);
    n1.attatch(d2, i1);
    d2.attatch(i2);
    n2.attatch(i3);
    i3.attatch(ed);
}
int main() {
    init();
    string s;
    int i;
    cin >> i;
    while (i--) {
        cin >> s;
        cout << (st.exec(s.begin()) ? "Yes" : "No") << endl;
    }
    return 0;
}
解法3 很多 if else
略
 本作品使用基于以下许可授权:Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
本作品使用基于以下许可授权:Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.
