سؤال

I am trying to write a function which takes a string as an argument and checks if that string contains only one non-alphanumeric character, if this is the case then return true, if not, return false.

For example:

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

My current code is below, but I don't feel that its working. As I have a count elsewhere which basically counts the true's. Done using a map which contains the strings. And the value which I am getting for the count is too high for the words that are being input.

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;}  
        }
     }
هل كانت مفيدة؟

المحلول 7

You aren't counting the number of non-alphanumeric characters in your code, do you? you just return true or false on the first character.

Unless you count, you won't find the answer. However, you can stop at the second non-alphanum.

Since you seem to need the exercise in writing code, here's some psuedo-code:

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

نصائح أخرى

You can use std::count_if and then check if the value is greater than 1.

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

Your program makes a decision after looking at only a single character; it cannot work like that! When you see that the character is alphanumeric, you return false right away, without looking at the remaining characters. To fix, move the return false outside the loop.

Other's have commented on how badly you've described your issues, and thrown complex template-based code at you that you probably don't understand. I strongly suggest that you read up on it; templates are powerful, useful, and a great programming technique. The downside is that you have to learn them first.

Here's a non-template oriented solution:

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

As "inefficient" as the next guy.

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

Posted just so I too can get down-voted for "thats not how i'd do it" reasons. I'd rather laugh with the sinners than cry with the saints.

You could use std::count_if and lambda:

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

You can use std::count_if in combination with std::isalnum.

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

The caveat is that this algorithm checks all the characters in the string. This may or may not be a performance issue.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top