soundex算法中的问题

时间:2017-11-11 10:32:51

标签: c++ c++11 soundex

我是C ++的初学者,我正在尝试理解我在互联网上找到的Soundex算法。我对其中的大部分内容都了解,但这并没有解释只是在某个地方发布,因此有几行代码我不太了解。

以下代码中实现的Soundex算法如下: http://www.blackwasp.co.uk/soundex.aspx

以下是代码:

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

using namespace std;

//----------------------------------------------------------------------------
char f_transform( char c )
  {
  string consonants[ 6 ] = { "BFPV", "CGJKQSXZ", "DT", "L", "MN", "R" };
  for (int i = 0; i < 6; i++)
    if (consonants[ i ].find( c ) != string::npos)
      return (i +1) +'0';
  return c;
  }

//----------------------------------------------------------------------------
string soundex( const string& s )
  {
  string result;

  // Validate s
  if (std::find_if(
        s.begin(),
        s.end(),
        std::not1(std::ptr_fun<int,int>(std::isalpha))
        )
      != s.end())
    return result;

  // result <-- uppercase( s )
  result.resize( s.length() );
  std::transform(
    s.begin(),
    s.end(),
    result.begin(),
    std::ptr_fun<int,int>(std::toupper)
    );

  // Convert Soundex letters to codes
  std::transform(
    result.begin() +1,
    result.end(),
    result.begin() +1,
    f_transform
    );

  // Collapse adjacent identical digits
  result.erase(
    std::unique(
      result.begin() +1,
      result.end()
      ),
    result.end()
    );

  // Remove all non-digits following the first letter
  result.erase(
    std::remove_if(
      result.begin() +1,
      result.end(),
      std::not1(std::ptr_fun<int,int>(std::isdigit))
      ),
      result.end()
    );

  result += "000";
  result.resize( 4 );

  return result;
  }

// end soundex.cpp 
除了两件事之外,我得到了大部分内容: 1.发生'字符串s的验证'的地方:

if (std::find_if(
        s.begin(),
        s.end(),
        std::not1(std::ptr_fun<int,int>(std::isalpha))
        )
      != s.end())
    return result;

我不太了解'ptr_fun'。我已经在谷歌上阅读了它,它应该采用指向函数的指针并返回一个函数对象。现在我猜测它是必需的,因为's.begin()'是一个函数,它返回一个迭代器,就像指向某个索引处向量中元素的指针一样。所以我们不能只将函数传递给'isalpha',我们需要以某种方式转换它。但是,对我来说并不完全清楚,如果可以的话,请为我“愚蠢”,以便我能更好地理解它。)。

  1. 我不明白的另一件事就是这些代码:

    //折叠相邻的相同数字   result.erase(     的std ::唯一的(       result.begin()+1,       result.end()       )     result.end()     );

    //删除第一个字母后面的所有非数字   result.erase(     的std ::的remove_if(       result.begin()+1,       result.end()       的std :: NOT1(STD :: ptr_fun(STD :: ISDIGIT))       )       result.end()     );

  2. 让我们以第一部分为例,因为解释一个也将清​​除另一个问题。 我做了一些谷歌搜索,发现“独特”应该“除去连续等效字符数组中的第一个”。并且'erase'应该擦除[first,last]范围内的元素,这意味着最后一个元素保留在那里并且不被删除。因此,如果代码的作者想要删除所有相邻的相同数字,为什么他不使用这样的东西:

    std::unique(result.begin() + 1, result.end() ); ??
    

    为什么还要使用'擦除'功能? 这就是我解释该代码的方式:

    • 如果我在那里传递'abaace','独特'功能将返回'abace',然后我们将删除('abace','e')然后我不知道这里应该发生什么。请解释一下你是否可以。谢谢你的阅读。

0 个答案:

没有答案