【问题标题】:Check if a string contains a non-alphanumeric character [closed]检查字符串是否包含非字母数字字符[关闭]
【发布时间】:2012-12-27 20:34:46
【问题描述】:

我正在尝试编写一个函数,该函数将字符串作为参数并检查该字符串是否仅包含一个非字母数字字符,如果是这种情况则返回 true,如果不是,则返回假的。

例如:

'Alex's' would return true. 
James..Warner would return false.

我当前的代码如下,但我觉得它不起作用。因为我在其他地方有一个计数,它基本上算得上是真的。使用包含字符串的地图完成。而且我得到的计数值对于正在输入的单词来说太高了。

bool Class3::filter(string word)
    {
        string s = word;
        int len = s.size();

        for (int i=0; i<len; i++)
        {   if(!isalnum(s[i])){
            return true;}
            else{return false;}  
        }
     }

【问题讨论】:

  • 让其他人发现你的代码中的错误是没有效率的。您应该使用调试器单步调试代码以找出问题所在。
  • 您想检查一个字符串是否只包含一个全数字字符 Alex's 会返回true?这是矛盾的。
  • 顺便说一句,对您的格式的评论。虽然我确定您认为 else{return false;} 是完全清晰的,但标准 C++ 格式是将大括号放在自己的行上,或者至少在左括号后添加一个返回字符,然后给出右括号自己的线。这允许整个代码块缩进,有助于提高可读性。
  • @juanchopanza 是的,你是对的,我没有编辑我的问题来说明我的实际意思。对不起。
  • 与问题无关,但isalnum[s[i]] 是未定义的行为。 &lt;ctype.h&gt; 中的 is... 函数不将 char 作为参数。

标签: c++ string character non-alphanumeric


【解决方案1】:

您的程序仅在查看单个字符后做出决定;它不能那样工作!当您看到该字符是字母数字时,您立即返回false,而不查看其余字符。要解决此问题,请将return false 移出循环。

【讨论】:

  • 实际上,我认为需要移出的是 return true ......更好的是使用正则表达式。
【解决方案2】:

您没有计算代码中非字母数字字符的数量,是吗?您只需在第一个字符上返回 true 或 false。

除非你数数,否则你不会找到答案。但是,您可以停在第二个非字母数字处。

由于您似乎需要编写代码的练习,这里有一些伪代码:

int nonalphas = 0;
for ( char in string )
    if ( char is nonalpha )
        nonalphas++;
        if ( nonalphas > 1 )
            break;
return nonalphas == 1;

【讨论】:

  • @KonradRudolph 那么“a..b”和“a.b”有什么区别?
  • 这个函数只是为了检查字符串是否“有效”,我认为你不需要区分无效字符串......至少,这就是我阅读“过滤器”的方式作为。
  • @gustaf 因为我误读了这个问题。你是对的,需要计数。天哪,这是一个糟糕的任务描述。
  • 哎呀,我以为他是在与一个已知值的数组进行比较——他知道该数组有 500 个有效(或无效等)条目,并且正在将他得到的结果与之进行比较。
  • -1,仅仅是因为您在本可以保持中立的情况下,除了您的答案和其他解决方案之外,您对所有其他答案都投了反对票。我认为您的答案也与此处的其他答案一样低效。
【解决方案3】:

您可以将std::count_ifstd::isalnum 结合使用。

bool filter(const std::string word)
{
  return std::count_if(word.begin(), word.end(), [](char c){ return !(std::isalnum(c));}) > 1;
}

需要注意的是,该算法会检查字符串中的所有字符。这可能是也可能不是性能问题。

【讨论】:

  • -1 表示无效。您并不总是需要计算所有字符。此外,对于那些甚至无法正确格式化代码的人来说,您的回答有点令人反感。所以,+0.5 ;)
【解决方案4】:

您可以使用std::count_if,然后检查该值是否大于1。

int i = std::count_if(str.begin(),str.end(),[](char c){ return !(std::isalnum(c)); });
return i > 1;

【讨论】:

  • -1 表示无效。阅读 cmets 到其他答案。 编辑,对不起,不仅无效,而且也不正确。
  • @gustafr 为什么不正确?提示:它适用于 OP 提供的两个示例。
  • 你是对的。我累了,应该去睡觉了。仍然-1效率低下,对不起:/
【解决方案5】:

您可以使用std::count_iflambda

bool filter(const std::string& s)
{
  if (std::count_if(s.begin(), s.end(), [](char c){ return !std::isalpha(c); }) == 1)
  {
    cout << s << ": contains one non-alpha charectors" << endl;
    return false;
  }

 cout << s << ": string contains alpha charectors only" << endl;
 return true;      
}

【讨论】:

  • 这取决于....是否需要效率并且刺痛很大
【解决方案6】:

其他人评论了您对问题的描述有多么糟糕,并向您抛出了您可能不理解的基于模板的复杂代码。我强烈建议您阅读它;模板功能强大、有用且是一种出色的编程技术。缺点是你必须先学习它们。

这是一个非面向模板的解决方案:

bool class3::filter(string word)
{
    //You aren't mutating word, so don't waste your time
    //(or memory) by copying it.  In fact, I'd (strongly)
    //recommend you utilize a constant pass by reference,
    //because by default that's what you're already doing,
    //so you were taking a copy of a copy.  Waste of memory!

    //Just init a count variable.
    int count=0;

    //Set up your for loop...
    for(int i=0; i<word.size(); i++)
    {
        if(!isalnum(word[i]))
        {
            //If a character doesn't match, increment your counter
            count++;
                            //If you want to, you can return false here if count>1 to improve efficiency -- depends on your end goal.
        }
    }
    //If you want exactly one non-alphanumeric, then return this.
    return count==1;
    //Or if it's a maximum of one non-alphanumeric, then...
    return count<=1;
    //Or you could generalize by returning a count of non alphanumerics -- remember to change the return type!
    return count;
}

【讨论】:

  • 我不是-1:因为你至少努力提供帮助,但是当计数> 1时继续寻找效率低下。请调整。
  • 它的本意是低效——并且尽可能简单(为了简单)。
  • @gustafr 另外,效率并不是一切。虽然这很容易提高效率并且应该采取,但早期优化是万恶之源!如果没有更好地了解他实际上想要完成的事情(因此我最后有三个返回选项),那么应该进行什么样的优化是有限度的。
【解决方案7】:

和下一个人一样“低效”。

#include <string>
#include <algorithm>
#include <functional>
#include <cctype>

// return 'true' if there is one-and-only-one non-alphanumeric character
// in the given std::string parameter. If there are NO non-alphanumeric
// characters, OR more than one, then return 'false'.
bool filter(const std::string& s)
{
    function<bool(char)> is_not_alnum([](char c)->bool{ return !isalnum(c); });
    string::const_iterator first = find_if(s.begin(), s.end(), is_not_alnum);
    return first != s.end() && (find_if(first+1, s.end(), is_not_alnum) == s.end());
}

发布只是为了让我也可以因为“我不会这样做”的原因而被否决。我宁愿和罪人一起笑,也不愿和圣徒一起哭。

【讨论】:

  • 您对与罪人大笑的评论为您赢得了 +1。也就是说......你的代码非常密集,我无法做出正面或反面。鉴于你是故意这样做的,那值得第二次 +1,可惜我不能给它!
  • @RonLugge 首先我们调用find_if 来获取第一个非alnum char,找不到一个返回false。如果我们找到一个,我们会再寻找一个从我们找到第一个位置开始的一个位置。如果没有找到另一个,我们返回true,否则返回false。具有讽刺意味的是,它最终与所选答案使用的算法非常相似。
  • 我不能完全理解它的一半原因是我近两年没有接触过 C++。与 C++ 开发人员相比,我更喜欢 Web 和 iOS 开发人员。事实上,我从来没有学过 STD 图书馆的大部分内容,因为我的老师在我大四之前对它的使用非常不满……到那时我或多或少地停止使用它,转而使用其他语言。当然,我的问题的另一半是您编写它的紧凑程度如何将其全部压缩为 3 行(为了清晰起见,我宁愿避免这样做,让编译器魔法来做这件事)
  • @RonLugge 哈哈。是的,我本可以进一步减少它,但是所有血腥的乐趣都从我屏幕上代码列表的右侧滚落。但它有效,所以至少我有这样的想法。 =P
猜你喜欢
  • 1970-01-01
  • 2016-05-19
  • 2015-01-04
  • 2011-07-11
  • 2020-12-12
  • 2014-07-16
  • 2011-05-08
  • 1970-01-01
相关资源
最近更新 更多