C++:从星号不是乘法符号的字符串中删除所有星号

标签 c++ algorithm performance erase

所以基本上,我可能有一些字符串看起来像:“嘿,这是一个字符串 * 这个字符串很棒 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 次逻辑运算。恕我直言,char s 映射到 int s,检查边界(char <= '9' && char >= '0')

关于C++:从星号不是乘法符号的字符串中删除所有星号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6862657/

相关文章:

c++ - gcc 编译/链接后的 .h~ 文件是什么?

c# - 使用多个连接和谓词优化 LINQ 查询

performance - 如何使用 shell 脚本进行性能测试 - 工具和技术?

android - 配置 WebRTC android 以获得最低延迟

c++ - auto a = A(3) 和 A a(3) 有什么区别?

c# - 如何在 C++ 和 ??? 中合法地编写:::在 C# 中?

c++ - OpenGL Shader 在 AMD 机器上不能正常工作

python - 使用 SlopeOne 算法预测玩家是否可以完成游戏中的关卡?

algorithm - 嵌套 for 循环中的迭代次数?

algorithm - 从给定长度的线段构造最大可能的矩形