题目
实现正规表达式中的".“及”*“的功能,其中”."表示匹配一个任务字符,“ * ”则重复前一字符任意数量(包括零)
结果
str =“aa”, exp =“a”
RES: 0
str =“aa”, exp =“a*”
RES: 1
str =“ab”, exp ="."
RES: 1
str =“aab”, exp =“c*a*b”
RES: 1
str =“mississippaai”, exp ="mis*is*ip."
RES: 0
str =“mississippi”, exp =“misisip*.”
RES: 1
代码
目前是先分析正则表达,再一个个匹配字符的做法,只针对 “ * ”做了结束循环的判断
后来发现这题其实是就是常见的深度优先遍历的题
碰到“ * ” 号时,从0~n个字符遍历后面第i个字符是否匹配
#include <iostream>
#include <vector>
#include <string>
class RegularExp {
public:
enum CharType {
NONE = 0x0,
FIX_CHAR = 0x01,
ANY_ONE = 0x02, //任意字符
PRE_ANY = 0x04 //前一个字符>=0个
};
struct AnalyseChar {
char c;
std::string str;
unsigned type;
};
RegularExp(const std::string& exp) {
analyse_exp(exp);
}
void analyse_exp(const std::string& exp_str) {
exps.clear();
for (std::size_t i = 0; i < exp_str.size(); ++i) {
char cur_c = exp_str.at(i);
if (cur_c == '.') {
exps.push_back(AnalyseChar{ cur_c, std::string(1, cur_c), CharType::ANY_ONE });
}
else if (cur_c == '*') {
if (exps.size() > 0) {
exps[exps.size() - 1].type |= CharType::PRE_ANY ;
}
}
else {
exps.push_back(AnalyseChar{ cur_c, std::string(1, cur_c), CharType::FIX_CHAR });
}
}
// 合并所有的固定的字符
if (false) {
auto pre_it = exps.end();
for (int i = 0; i < exps.size() - 1; ++i) {
if (exps[i].type == CharType::FIX_CHAR) {
for (auto it = exps.begin() + i + 1; it != exps.end();)
{
if (it->type == CharType::FIX_CHAR) {
exps[i].str += it->str;
it = exps.erase(it);
continue;
}
else {
break;
}
++it;
}
}
}
}
}
bool _try_compare_str2(const std::string& str, std::size_t str_index, std::size_t exp_index) {
if (str_index >= str.size()) {
return (exp_index >= exps.size());
}
if (exp_index >= exps.size()) {
return (str_index >= str.size());
}
char c = str.at(str_index);
AnalyseChar ac = exps[exp_index];
if (ac.type & CharType::PRE_ANY) {
for (std::size_t i = 0; i < str.size() - str_index; ++i) {
if ((ac.type & CharType::ANY_ONE) || str.at(str_index + i) == ac.c) {
if (_try_compare_str2(str, str_index + i, exp_index + 1)) {
return true;
}
}
else {
return _try_compare_str2(str, str_index + i, exp_index + 1);
}
}
return true;
}
else{
// 非循环
if ((ac.type & CharType::ANY_ONE) || ((ac.type & CharType::FIX_CHAR) && c == ac.c)) {
return _try_compare_str2(str, str_index + 1, exp_index + 1);
}else {
return false;
}
}
}
bool try_compare_str2(const std::string& str) {
return _try_compare_str2(str, 0, 0);
}
std::vector<AnalyseChar> exps;
};
void compare_str() {
int count = 2 *7;
const std::string all_test_str[] = {
"aa", "a",
"aa", "a*",
"ab", ".*",
"aab", "c*a*b",
"bbb", "b*b",
"mississippaai", "mis*is*ip*.",
"mississippi", "mis*is*ip*."
};
std::cout << std::endl;
for (int i = 0; i < count; i+=2) {
const std::string& test_str = all_test_str[i];
const std::string& exp_str = all_test_str[i+1];
RegularExp reg(exp_str);
bool res = reg.try_compare_str2(test_str);
std::cout << "str =\"" << test_str << "\", exp =\"" << exp_str << "\""
<< std::endl << "RES: " << res << std::endl;
}
}