华为OD试题-最长合法表达式 C++
参数最长合法表达式
题目
提取字符串中的最长合法简单数学表达式
字符串长度最长的,并计算表达式的值。
如果没有返回0.
简单数学表达式只能包含以下内容:
0 - 9数字,符号 + - *
说明 :
1.所有数字,计算结果都不超过 long
2.如果有多个长度一样的,请返回第一个表达式的结果
3.数学表达式,必须是最长的,合法的
4.操作符不能连续出现,如 +--+1 是不合法的
输入
字符串
输出描述
表达式值
示例
输入
1 - 2abcd
输出
1
解题思路及解题代码:
用正则表达式解,我的方式比较粗暴,所以大家就参考一下吧
这里进行对裁剪好的字符串的计算,也是使用正则表达式判断数字的位置,因为regex_search这个函数在匹配的时候会返回匹配字符串的包含首地址(frist)和不包含的结束地址(second)恰好是运算符的位置,所以遍历的同时也可以记录运算符。
默认第一个运算符是+,先运算再更新运算符。
int calculateExpression(string& expression) {
regex pattern("(\\d{1,10})");
smatch match;
string::const_iterator citer = expression.cbegin();
int result = 0;
char op = '+';
while (regex_search(citer, expression.cend(), match, pattern))//循环匹配
{
citer = match[0].second;
switch (op)
{
case '+':
result += stoi(match[0].str());
break;
case '-':
result -= stoi(match[0].str());
break;
case '*':
result *= stoi(match[0].str());
break;
default:
break;
}
if (citer != expression.cend())
{
op = *citer;
}
}
return result;
}
删除字符串中的空格,否则影响正则表达式的匹配。
void trim(string& s)
{
int index = 0;
if (!s.empty())
{
while ((index = s.find(' ', index)) != string::npos)
{
s.erase(index, 1);
}
}
}
///\主函数对输入字符进行合法算式的匹配,保存最长的表达式字符串索引。
int main()
{
//string input;
//getline(cin, input);
string str = "aaavvvdddeee4-4+6fff333+5+9+ 12 -1000++++++5555_5555avg444+5h90hhh1+2abc";
trim(str);
regex pattern("(\\d{1,10})((([+]\\d{1,10})|([*]\\d{1,10})|([-]\\d{1,10}))*)");
smatch match;
string::const_iterator citer = str.cbegin();
vector<string>strs;
int lens = 0,max = 0,index = 0,maxIndex = 0;
while (regex_search(citer, str.cend(), match, pattern))//循环匹配
{
citer = match[0].second;
cout << match[0] << endl;
strs.push_back(match[0]);
lens = match[0].str().size();
if (max <= lens)
{
max = lens;
maxIndex = index;
}
index++;
}
cout << calculateExpression(strs[maxIndex]);
return 0;
}
参考文章:
C++11之正则表达式(regex_match、regex_search、regex_replace)_c++ regex_replace-CSDN博客
【C++】去除字符串string中的空格(两头空格、所有空格)_c++ string去除空格-CSDN博客