-3

making a function that determines if two strings are equal but ignores their case. So far I have

bool isEqual(string str1, string str2) {
    bool result = true;
    for(int i = 0; I < str1.length(); i++) {
        if(str1[i]==str2[i]||str1[i]==toupper(str2[i])||str1[i]==tolower(str2[i])){
            //keep result==true
        }
        else {
            result = false;
        }
    }
return result;
}

But this seems like a really inefficient way to do the logic of this problem, does anybody have any suggestions? Thanks

  • If you don't know the encoding, it can't be done. If you do know the encoding, you'll need to use that encoding to help do it. If you are working with Unicode, use fold case to ignore case. – Eljay Mar 10 '19 at 23:48
  • Not only is the shown code inefficient, it is also wrong, and will result either in undefined behavior, or a wrong result, with strings of different length. Start by fixing your code so that it gives a correct result with strings of different length, then see if you can figure out how to make exactly one comparison in the `if()` statement, which will then be as "efficient" as it possibly can be. – Sam Varshavchik Mar 10 '19 at 23:50
  • Instead of `result = false;` just `return false;`. No need to go on checking after a mismatch. – Pete Becker Mar 10 '19 at 23:59

1 Answers1

0

My suggestion.

  1. Use iterators instead of the array operator with an index.
  2. Iterate on both the inputs.
  3. Use std::tolower() or std::toupper() on all characters when comparing them.
  4. Return immediately when you know the answer.

bool isEqual(string str1, string str2)
{
   auto iter1 = begin(str1);
   auto end1 = end(str1);

   auto iter2 = begin(str2);
   auto end2 = end(str2);

   for ( ; iter1 != end1 && iter2 != end2; ++iter1, ++iter2 )
   {
      // This will also work.
      // if ( std::tolower(*iter1) != std::tolower(*iter2) )

      if ( std::toupper(*iter1) != std::toupper(*iter2) )
      {
         return false;
      }
   }

   // We come here only if we have compared all the characters
   // of at least one of the strings.

   // The two strings are equal only if we have compared all the
   // characters of BOTH the strings.

   return (iter1 == end1 && iter2 == end2);
}

A simpler version would be to compare the lengths of the strings at the start and return false if they are of unequal lengths. Thanks are due to @PeteBecker for the suggestion.

bool isEqual(string str1, string str2)
{
   if ( str1.length() != str2.length() )
   {
      return false;
   }

   auto iter1 = begin(str1);
   auto end1 = end(str1);

   auto iter2 = begin(str2);
   auto end2 = end(str2);

   for ( ; iter1 != end1 && iter2 != end2; ++iter1, ++iter2 )
   {
      // This will also work.
      // if ( std::tolower(*iter1) != std::tolower(*iter2) )

      if ( std::toupper(*iter1) != std::toupper(*iter2) )
      {
         return false;
      }
   }

   // We come here only if we have compared all the characters
   // of BOTH the strings. In that case the strings are equal.

   return true;
}
R Sahu
  • 204,454
  • 14
  • 159
  • 270