使用ispunct()删除标点符号

时间:2013-08-31 05:12:41

标签: c++ c

当单词以这种方式分开时,

ispunct()效果很好"one, two; three"。然后它将删除“,;”并用给定的字符替换。

但如果以这种方式"ts='TOK_STORE_ID';"给出字符串,那么它将"ts='TOK_STORE_ID';"作为一个单一标记,或

"one,one, two;four$three two"作为三个令牌1. "one,one" 2. "two;four$three" 3. "two"

是否有任何一个可以将"one,one, two;four$three two"视为"one one two four three two"每个单独的令牌?

编写手动代码,如:

for(i=0;i<str.length();i++)
{
  //validating each character
}

当字符串非常长时,此操作将变得非常昂贵。

那么还有像ispunct()这样的其他功能吗?或其他什么?

在c中,我们这样做来比较每个角色:

  for(i=0;i<str.length();i++)
    {
      if(str[i]==',' || str[i]==",") // Is there any way here to compare with all puctuations in one shot?
        str[i]=" "; //replace with space

    }

在c ++中,正确的方法是什么?

4 个答案:

答案 0 :(得分:5)

This operation will become very costly when string is very very long.

不,它不会。它将是一个O(n)操作,可以解决这个问题。对于此操作,您不可能比这更好,因为无论哪种方式,您都必须查看字符串中的每个字符。如果不查看字符串中的每个字符,就无法做到这一点。

答案 1 :(得分:4)

假设您正在处理典型的8位字符集,我首先要构建一个转换表:

std::vector<char> trans(UCHAR_MAX);

for (int i=0; i<UCHAR_MAX; i++)
    trans[i] = ispunct(i) ? ' ' : i;

然后处理一串文本可以是这样的:

for (auto &ch : str)
    ch = trans[(unsigned char)ch];

对于8位字符集,转换表通常都适合您的L1缓存,并且循环只有一个高度可预测的分支(除了到达字符串的末尾时总是被占用)所以它应该是相当快。

要明确的是,当我说“相当快”时,我的意思是非常不太可能这是你所描述的过程中的瓶颈。您需要慢速处理器和快速网络连接的组合,才能成为处理通过网络获取的数据的瓶颈。

如果你有一个带有10 GbE网络连接的Raspberry Pi,可能需要做更多的优化工作才能跟上(但我还不确定)。对于任何不那么激进的不匹配,网络显然将成为瓶颈。

答案 2 :(得分:1)

So is there any other function like ispunct()? or anything else?

事实上,有。 man ispunct给了我这个漂亮的清单:

int isalnum(int c);
int isalpha(int c);
int isascii(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);

拿你想要的任何一个。

答案 3 :(得分:0)

您还可以使用std::remove_copy_if完全删除标点符号:

#include <algorithm>
#include <string>      

  string words = "I,love.punct-uation!";
  string result;  // this will be our final string after it has been purified

  // iterates through each character in the string
  // to remove all punctuation
  std::remove_copy_if(words.begin(), words.end(),            
                    std::back_inserter(result), //Store output           
                    std::ptr_fun<int, int>(&std::ispunct)  
                   );

  // ta-da!
  cout << result << endl;