Рассматривая только одно слово, вот деструктивный алгоритм O (n log n):
std::string::iterator unq_end = std::unique( word.begin(), word.end() );
std::sort( word.begin(), unq_end );
return std::unique( word.begin(), unq_end ) == unq_end;
Редактировать: Первый вызов unique
уменьшает количество последовательных букв до отдельных букв. Призыв к sort
группирует одинаковые буквы. Второй вызов unique
проверяет, образовались ли sort
какие-либо новые группы последовательных букв. Если это так, то слово не должно быть сгруппировано.
Преимущество перед другими опубликовано в том, что он не требует хранения - хотя это не так много преимуществ.
Вот простая версия альтернативного алгоритма, также требующая только O (1) хранилища (и да, также проверенная):
if ( word.empty() ) return true;
bitset<CHAR_MAX+1> symbols;
for ( string::const_iterator it = word.begin() + 1; it != word.end(); ++ it ) {
if ( it[0] == it[-1] ) continue;
if ( symbols[ it[0] ] ) return false;
symbols[ it[-1] ] = true;
}
return ! symbols[ * word.rbegin() ];
Обратите внимание, что вам потребуются незначительные изменения для работы с символами вне ASCII. bitset
исходит из заголовка <bitset>
.