所以基本上,我可能会看到一些字符串:“嘿,这是一个字符串*这个字符串很棒97 * 3 = 27 *这个字符串很酷”.
但是,这个字符串可能很大.我试图从字符串中删除所有星号,除非星号似乎表示乘法.效率在这里有点重要,我很难找到一个好的算法来从中删除所有非乘法星号.
为了确定星号是否用于乘法,我显然可以检查它是否夹在两个数字之间.
因此,我以为我可以做一些像(伪代码)的事情:
wasNumber = false Loop through string if number set wasNumber = true else set wasNumber = false if asterisk if wasNumber if the next word is a number do nothing else remove asterisk else remove asterisk
然而,在一个巨大的字符串上,这是丑陋和低效的.您能想到在C中实现这一目标的更好方法吗?
另外,我怎么能真正检查一个单词是否是一个数字?它被允许为小数.我知道有一个函数来检查一个字符是否是一个数字……
解决方法
功能齐全的代码:
#include <iostream> #include <string> using namespace std; string RemoveAllAstericks(string); void RemoveSingleAsterick(string&,int); bool IsDigit(char); int main() { string myString = "hey this is a string * this string is awesome 97 * 3 = 27 * this string is cool"; string newString = RemoveAllAstericks(myString); cout << "Original: " << myString << "\n"; cout << "Modified: " << newString << endl; system("pause"); return 0; } string RemoveAllAstericks(string s) { int len = s.size(); int pos; for(int i = 0; i < len; i++) { if(s[i] != '*') continue; pos = i - 1; char cBefore = s[pos]; while(cBefore == ' ') { pos--; cBefore = s[pos]; } pos = i + 1; char cAfter = s[pos]; while(cAfter == ' ') { pos++; cAfter = s[pos]; } if( IsDigit(cBefore) && IsDigit(cAfter) ) RemoveSingleAsterick(s,i); } return s; } void RemoveSingleAsterick(string& s,int i) { s[i] = ' '; // Replaces * with a space,but you can do whatever you want } bool IsDigit(char c) { return (c <= 57 && c >= 48); }
顶级概述:
代码搜索字符串直到遇到*.然后,它查看*之前和之后的第一个非空白字符.如果两个字符都是数字,则代码确定这是乘法运算,并删除星号.否则,它将被忽略.
如果您需要其他详细信息,请参阅此帖子的修订历史记录.
重要笔记:
>您应该认真考虑在字符串上添加边界检查(即,不要尝试访问小于0或大于len的索引
>如果您担心括号,请更改检查空格的条件以检查括号.
>检查每个字符是否都是数字是一个坏主意.至少,它需要两次逻辑检查(参见我的IsDigit()函数). (我的代码检查’*’,这是一个逻辑操作.)然而,发布的一些建议非常糟糕.不要使用正则表达式来检查字符是否为数字.
既然你在问题中提到了效率,而且我没有足够的代表点来评论其他答案:
检查’0”1”2’…的switch语句意味着每个不是数字的字符必须经过10次逻辑操作.请充分尊重,因为字符映射到整数,只需检查边界(字符< ='9'&& char> =’0′)