Вопросы по алгоритму 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’. Я читал об этом в Google, и он должен взять указатель на функцию и вернуть объект функции. Теперь я предполагаю, что это необходимо, потому что s.begin () — это функция, которая возвращает итератор, который похож на указатель на элемент в векторе с определенным индексом. Поэтому мы не могли просто передать функцию в isalpha, и нам нужно было как-то ее преобразовать. Тем не менее, это не совсем понятно для меня, поэтому, пожалуйста, «потише», если можно, чтобы я мог лучше понять :).

  1. Еще одна вещь, которую я не понимаю, это следующие строки кода:

    // Свернуть соседние одинаковые цифры
    result.erase (
    станд :: уникальный (
    result.begin () +1,
    result.end ()
    ),
    result.end ()
    );

    // Удалить все не цифры после первой буквы
    result.erase (
    станд :: remove_if (
    result.begin () +1,
    result.end (),
    станд :: not1 (станд :: ptr_fun (станд :: isdigit))
    ),
    result.end ()
    );

Возьмем, к примеру, первую часть, так как объяснение одной части прояснит и другой вопрос.
Я немного погуглил и обнаружил, что «unique» должен «удалять все, кроме первого, в массиве последовательных эквивалентных символов». И «стереть» должен стереть элементы в диапазоне [первый, последний), что означает, что последний элемент остается там и не удаляется. Поэтому, если автор кода хотел удалить все соседние идентичные цифры, почему он просто не использовал что-то вроде этого:

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

Зачем также использовать функцию «стереть»?
Вот как я интерпретирую этот код:

  • если я передам там «abaace», то «уникальная» функция вернет «abace», и тогда мы удалили бы («abace», «e»), и тогда я не знаю, что здесь произойдет. Пожалуйста, объясните, если можете. Спасибо за чтение.

4

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]