代码审查,C++,字谜方法

Code review, C++, Anagram method

本文关键字:方法 C++ 代码审查      更新时间:2023-10-16

我正在做一些"破解编码面试"一书中的练习题,想让一些人审查我的代码中的错误和优化。任何反馈将不胜感激。

问题:编写一个方法来确定两个字符串是否是字谜。

/*
Time complexity: O(n^2)
Space complexity: O(n)
*/
bool IsAnagram(std::string str1, std::string str2)
{
    if(str1.length() != str2.length())
        return false;
    for(int i = 0; i < str1.length();i++)
    {
        bool found = false;
        int j = 0;
        while(!found && j < str2.length())
        {
            if(str1[i] == str2[j])
            {
                found = true;
                str2[j] = NULL;
            }
            j++;
        }
        if(!found)
            return false;
    }
    return true;
}

这通常更有效

#include <iostream>
#include <string>
#include <algorithm>
bool IsAnagram(std::string& str1, std::string& str2)
{
  if(str1.length() != str2.length())
    return false;
  std::sort(str1.begin(), str1.end());
  std::sort(str2.begin(), str2.end());
  return str1.compare(str2) == 0;
}
int main(int argc, char* argv[])
{
  std::string an1("army");
  std::string an2("mary");
  if(IsAnagram(an1, an2)) 
    std::cout << "Hooray!n";
    return 0;
}

对于那些不喜欢变异字符串的人来说,也许这是一个更好的选择。可以删除对参数 1 和 2 的引用,也可以在函数内部复制,如下所示。 这样,参数可以是恒定的。

bool IsAnagram2(const std::string& str1, const std::string& str2)
{
   if(str1.length() != str2.length())
      return false;
   std::string cpy1(str1), cpy2(str2);
   std::sort(cpy1.begin(), cpy1.end());
   std::sort(cpy2.begin(), cpy2.end());
   return cpy1.compare(cpy2) == 0;
}

O(n)算法。 不要排序(这是O(n lg n)),而是计算 s1 中的字符出现次数,并将其与 s2 中的字符出现次数进行比较。

#include <string>
#include <iostream>
#include <limits>
bool IsAnagram(const std::string& s1, const std::string& s2)
{
  if (s1.size() != s2.size()) {
    return false;
  }
  int count[std::numeric_limits<char>::max() + (std::size_t)1] = {};
  for (auto c : s1) {
    count[c]++;
  }
  for (auto c : s2) {
    if (!count[c]) {
      return false;
    }
    count[c]--;
  }
  return true;
}
int main(int argc, char **argv)
{
  std::cout << IsAnagram(argv[1], argv[2]) << std::endl;
  return 0;
}

已经有标准的算法std::is_permutation可以简单地执行任务

#include <iostream>
#include <iomanip>
#include <string>
#include <algorithm>

int main() 
{
    std::string s( "aab" );
    std::string t( "aba" );
    std::cout << std::boolalpha 
              << ( s.size() == t.size() && 
                   std::is_permutation( s.begin(), s.end(), t.begin() ) )
              << std::endl;
    return 0;
}

输出为

true

所以ypu所需要的只是看看算法是如何实现的:)

如果你想要一个单独的函数,那么它看起来像

bool IsAnagram( const std::string &s1, const std::string &s2 )
{
    return s1.size() == s2.size() &&
           std::is_permutation( s1.begin(), s1.end(), s2.begin() );
}         

使用 std::sort 不是一个好方法,因为原始字符串将被更改,或者您必须按值将它们传递给函数。