C++ 检查字符串是否包含非字母数字字符

C++ 检查字符串是否包含非字母数字字符,c++,string,character,non-alphanumeric,C++,String,Character,Non Alphanumeric,我正在尝试编写一个函数,它将字符串作为参数,并检查该字符串是否只包含一个非字母数字字符,如果是这种情况,则返回true,如果不是,则返回false 例如: 'Alex's' would return true. James..Warner would return false. 我当前的代码如下,但我觉得它不起作用。因为我在其他地方有一个计数,基本上是真的。使用包含字符串的映射完成。我得到的计数值对于输入的单词来说太高了 bool Class3::filter(string word)

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

例如:

'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;}  
        }
     }

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

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

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

由于您似乎需要编写代码的练习,下面是一些psuedo代码:

int nonalphas = 0;
for ( char in string )
    if ( char is nonalpha )
        nonalphas++;
        if ( nonalphas > 1 )
            break;
return nonalphas == 1;
您可以与结合使用

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

您可以使用std::count\u if,然后检查该值是否大于1

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


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

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

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;
}

跟下一个家伙一样没效率

#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());
}


贴出来只是为了让我也能被投票支持,但我不会这么做。我宁愿和罪人一起笑,也不愿和圣人一起哭。

让别人发现你代码中的错误是徒劳的。您应该使用调试器逐步检查代码以找出错误所在。是否要检查字符串是否仅包含一个alhpanumeric字符,并且Alex的将返回true?这是矛盾的。顺便说一句,对你的格式的评论。虽然我确信你认为其他的{返回false;}是完全易读的,标准C++格式是把卷筒括号放在它们自己的行上,或者至少在打开的括号之后添加返回字符,然后给它的括号是自己的行。这允许整个代码块缩进,有助于提高可读性。@juanchopanza是的,你是对的,我没有编辑我的问题来显示我的实际意思。抱歉。与问题无关,但isalnum[s[i]]是未定义的行为。问题是。。。中的函数不以char作为参数。实际上,我认为需要移出的是返回true。。。更好的可能是使用正则表达式。@KonradRudolph那么a..b和a.b有什么区别呢?这个函数只是检查字符串是否“有效”,我认为您不需要区分无效字符串。。。至少,这就是我将“过滤器”解读为“古斯塔夫”的方式,因为我误读了这个问题。你说得对,数数是必要的。我的天,这是一个糟糕的任务描述。哦,我以为他在与一个已知值数组进行比较-他知道该数组有500个有效或无效的条目,并将他得到的结果与之进行比较。-1,只是因为除了你的答案和一个其他解决方案之外,你在本可以保持中立的情况下对其他所有答案进行了否决。我认为你的答案也和其他答案一样低效。——1是无效的。您并不总是需要计算所有字符。而且,你的答案对那些甚至不能正确格式化代码的人来说有点像是在当面打耳光。因此,+0.5-1表示无效。阅读其他答案的评论。编辑,对不起,不仅无效,而且也不正确。@gustafr为什么不正确?提示:它适用于OP提供的两个示例。你是对的。我累了,应该去睡觉了。仍然-1表示效率低下,抱歉:/I我不是-1:ing,因为你至少会尽力提供帮助,但当count>1时继续查找是没有效率的。请调整一下。这意味着效率不高,而且尽可能简单。@gustafr同样,效率不是一切。虽然这是一个简单的效率增益,应该采取,早期优化是万恶之源!如果没有更好的了解他到底想要实现什么,那么为什么我在最后有三个回报选项,应该做什么样的优化是有限制的。这取决于。。。。如果效率是必需的,而刺痛是巨大的,你对与罪人一起大笑的评论为你赢得+1。也就是说。。。你的代码太密集了,我弄不清它的头绪。考虑到你是故意这么做的,这也值得一秒钟+1
我不能给它@RonLugge首先我们调用find_,如果要获取第一个非alnum字符,则查找失败返回false。如果我们找到了一个,我们会再找一次,从找到第一个的位置开始再找一个。如果没有找到另一个,则返回true,否则返回false。具有讽刺意味的是,它最终与所选答案的算法非常类似。我不能做的头或尾的原因是我在近两年没有接触过C++。我比我是一个C++开发者更像一个网络和iOS开发者。事实上,我从来没有学到过大部分的STD图书馆,因为我的老师们皱眉头,沉重地,直到它的使用直到我的大一年…到那时,我或多或少地停止使用它,转而使用其他语言。当然,我的另一半问题是,你写得有多紧凑,把它浓缩成3行,为了清晰起见,我宁愿避免这样做,让编译器魔法来完成它thing@RonLugge哈哈。是的,我本可以进一步减少它,但是所有血腥的乐趣都从我屏幕上代码列表的右侧滚了下来。但它是有效的,所以至少我能做到这一点=P
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;
}
#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());
}