Nano Hash - криптовалюты, майнинг, программирование

С++ как определить, стоит ли одно слово перед другим в алфавите

Я использую функцию sort() в C++ для сортировки вектора объектов типа «Игра», который я определил сам. Для этого я вручную пишу функцию, которая будет действовать вместо operator< и которая будет передана в качестве третьего параметра в функцию sort(). Во-первых, я сравниваю по баллам. Затем, если счет равный, я сравниваю по названию команды.

Что мне нужно, так это функция alphabetical(string s1, string s2), которая вернет true, если s1 окажется перед s2 в словаре. Например:

alphabetical("aardvark", "apple"); //true
alphabetical("balloon", "zebra"); //true
alphabetical("zebra", "apple"); //false

Я также хочу, чтобы он возвращал false, если строки идентичны. Есть ли что-то в библиотеке, что я мог бы использовать? Или как мне написать функцию? Надеюсь, я ясно выразился.


  • Если все в нижнем регистре ASCII без специальной последовательности сопоставления, вы можете использовать strcmp. 11.09.2012
  • Вы также можете использовать std::lexicographical_compare. 11.09.2012
  • operator< и operator> работают со строками (я думаю). Потому что "a" < "b" возвращает true (хотя мой компилятор предупреждает, что это поведение undefined). 11.09.2012
  • @David, это сравнение адресов. Никогда не надежен. Однако std::string поддерживает operator< и т. д. 11.09.2012
  • @David: "a" < "b" сравнивает char*; вместо этого вы хотите std::string("a") < std::string("b"), за исключением, конечно, любых неявных преобразований, которые вы могли бы использовать. 11.09.2012
  • @chris неправда - это всегда надежно, просто оно не делает то, что кажется :-) на других языках высокого уровня 11.09.2012
  • std::string::operator<() определяется как эквивалент std::lexicographical_compare(). Поэтому, если у вас есть char*, вы должны просто использовать последний. 11.09.2012
  • @AdrianCornish, да, я просто имел в виду, что у вас почти нет возможности сказать, что это будет, прежде чем вы попробуете. 11.09.2012
  • @chris просто пошутил над твоим ответом ;-) 11.09.2012

Ответы:


1

std::string реализует лексикографический оператор сравнения "меньше", а это означает, что stringA < stringB обычно должен делать то, что вы хотите. Если вы создадите std::list<std::string> words, сортировка по алфавиту будет такой же простой, как words.sort();

В вашем пользовательском классе Game оператор сравнения "меньше" может быть реализован просто так:

return (score < rhs.score) || (score == rhs.score && team < rhs.team)

Стоит отметить, что лексикографическая сортировка не всегда будет такой, как ожидает человек. Джефф Этвуд обсуждает так называемый «естественный порядок сортировки» и лексикографический порядок сортировки в этот пост. Его пост также предоставляет ресурсы, из которых вы сможете найти алгоритмы, если такая сортировка вам нужна.

11.09.2012
  • не только символы и числа, которые кто знает, что можно было бы ожидать, когда они говорят по алфавиту, но и чувствительность к регистру становится проблемой. Смотрите мой ответ и ответы другим здесь. 11.09.2012
  • @CrazyEddie Спасибо за разъяснение! 11.09.2012
  • Названия моих команд таковы, что первый символ пишется с большой буквы, а все остальные строчные. Оператор ‹ работает. 11.09.2012

  • 2

    Стандартное сравнение строк будет работать, если все ваши строки являются верхними или нижними. Я считаю, что он работает даже с кодировками символов, которые больше не используются, такими как EBSIDIC или что-то в этом роде.

    Если у вас будет смешанный регистр, это не сработает, потому что «A» больше, чем «z». Чтобы это работало, вам нужно использовать такие вещи, как stricmp или что-то еще. Вы также можете переопределить char_traits для вашей основной_строки, чтобы сделать нечувствительное сравнение.

    Если вы хотите написать сортировку так, чтобы она помещала «A» перед «a» или наоборот, но «b» после «a»... тогда вам нужно будет написать свой собственный. Это должно быть довольно просто, используя таблицу ASCII, которую сегодня использует большинство операционных систем.

    Если вам нужно поддерживать языки, отличные от английского, проблема на самом деле становится нетривиальной.

    11.09.2012

    3

    Если вы используете std::string, вы можете просто использовать <. Но если у вас уже есть char*, вы не хотите (или не можете) его менять и хотите избежать накладных расходов на преобразование в std::string, тогда вы можете использовать std::lexicographical_compare().

    Конечно, в обоих случаях вам, вероятно, понадобится сравнение без учета регистра. Навскидку я не уверен, что правильное решение для std::string, возможно, что-то связанное с char_traits, но для lexicographical_compare() вы можете предоставить компаратор:

    bool alphabetical(const char *str1, const char *str2) {
        return std::lexicographical_compare(str1, &str1[strlen(str1)], str2, &str2[strlen(str2)], [](char a, char b){
            return tolower(a) < tolower(b);
        });
    }
    
    11.09.2012
  • @CrazyEddie, не так ли? Что тогда? Прошло много времени с тех пор, как я смотрел или использовал его, но я думал, что он будет в алфавитном порядке (по крайней мере, с учетом регистра). 11.09.2012
  • @chris - При сравнении лексики, которое представляет собой просто сравнение кода, «A» идет после «z». В алфавитном порядке мы, по крайней мере, ожидаем, что и «а», и «А» будут стоять перед «б» или «В». Это можно воспроизвести с помощью нечувствительного сравнения лексики. Если «A» должно стоять перед «a», то ничего стандартного не получится. 11.09.2012
  • @CrazyEddie: Вы делаете хорошее замечание, но вам не нужно было голосовать против всех остальных ответов, кроме вашего. 11.09.2012
  • @ Кевин - я сделал, если я думаю, что остальные неправы. Я минусую неправильные ответы. Если вас это беспокоит, я думаю, вырастите пару. Голосование за бесполезные ответы. Неправильные ответы хуже, чем бесполезные ИМО. 11.09.2012
  • @CrazyEddie: Незначительные проблемы в правильных ответах не делают весь ответ бесполезным. Если вы видите ошибку, вы можете прокомментировать ее, указав на нее и дав автору ответа время на исправление ошибки. Только если ответ в целом неверен, вы должны пойти дальше и проголосовать против. 11.09.2012
  • Останови блудливую карму, чувак. Это просто баллы. Ты был неправ, будь прав в следующий раз... и не плачь об этом. 11.09.2012
  • @CrazyEddie: Какой ты невероятно грубый человек. Это место для обсуждения кодирования, а не для того, чтобы тешить собственное эго. Боже мой, какой порыв вы, должно быть, испытали, когда ваши орлиные глаза заметили небольшую ошибку в чужом ответе, и как быстро ваша рука была на этой мыши, когда вы набросились, чтобы проголосовать за этот другой ответ, тем самым гарантируя, что ваш собственный ответ был в верхней части стопки. 11.09.2012
  • Да, это мое эго нужно гладить ... вот почему я сильно волнуюсь из-за того, что мне поставили минус 2 из-за того, что кто-то проголосовал против меня. Держу пари, это был ты, голосование мести... но кто плачет? Назвав меня грубым из-за того, что я проголосовал против вашего просто неправильного ответа, это не заставит меня отменить голосование. На самом деле, теперь, когда вы это сделали... вы не сможете заставить меня отменить это... что, как вы заметите, я сделал с другим, увеличив его баллы даже выше, чем мои были до вашего голосования мести. . Посмотрите в зеркало или что-то в этом роде. Выпей что ли... 11.09.2012
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..