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

Перегрузка оператора сравнения в C++ приводит к недопустимому оператору‹

В настоящее время пытается отсортировать вектор объекта, каждый объект которого содержит строку, в C++

Строки могут содержать буквы или цифры (из-за конструктивных ограничений это необходимо, так как компаратор может быть изменен).

На данный момент класс объекта перегружен, так что при сравнении двух объектов сравниваются содержащиеся в них строки. Это работает до определенного момента, однако, когда я использую операцию сортировки (например, сортировку STL) для упорядочения объектов, она будет сортировать три строки, такие как «1», «4», «12», в порядке «1», «12», «4». 4 больше 12, но поскольку сравнение начинается с самой левой цифры, возникает эта «неправильная» сортировка.

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

// overloaded comparision operators
friend bool operator<(const nodeRecord & record1, const nodeRecord & record2){
    // we need to deal with strings of different lengths...
    if(record1.comparator.length() < record2.comparator.length())
        return true;
    else
        return (record1.comparator < record2.comparator);
}

Эта операция приводит к появлению сообщения «Выражение: недопустимый оператор‹» во время выполнения.

Любые идеи относительно того, где я делаю ошибку? Кажется, я должен иметь возможность указать операции, как именно я хочу, чтобы операция сортировки происходила, даже если она недействительна, поскольку в настоящее время я использую вектор для хранения объектов.

Компаратор при инициализации объекта nodeRecord:

nodeRecord(int fromNode, int toNode, int connectionCost, bool compareByCost = false){
    // take the provided stock information and insert it into the object
    stringstream fromNodeSS;
    fromNodeSS << fromNode;
    this->fromNode = fromNodeSS.str();
    stringstream toNodeSS;
    toNodeSS << toNode;
    this->toNode = toNodeSS.str();
    this->connectionCost = connectionCost;

    // set the comparator to our chosen comparision term
    if (!compareByCost){
        this->comparator = this->fromNode; // we use from node in this case, since we build the tree outwards
    }
    else{
        stringstream ss;
        ss << this->connectionCost;
        this->comparator = ss.str(); // we use the connection cost in this case, to allow us to sort new connections
    }

    // set this as a non-null (active) record
    this->nullRecord = false;
}

  • Что такое компаратор? Опубликуйте код для этого. 26.04.2011
  • не могли бы вы показать определение компаратора? 26.04.2011
  • @Mike и @Mario -- компаратор инициализируется во время инициализации объекта nodeRecord. Вы можете увидеть это выше. 26.04.2011

Ответы:


1

Ваш оператор фактически недействителен.

Оператор < должен иметь ряд математических свойств, если вы хотите, чтобы его можно было использовать для сортировки. Одним из них является свойство AntiSymmetry:

x < y => !(y < x)

Давайте определим x = "b" и y = "aa".

  • x < y, потому что длина "b" меньше длины "aa"
  • y < x потому что "aa" уступает "b"

Хм?

Также обратите внимание, что ваше определение странно для чисел, если они имеют префикс 0s.

О, и сравнение строк намного медленнее, чем сравнение чисел.

Мое мнение? Прекратите изменять узел с информацией для сравнения. Фактический режим сравнения не имеет ничего общего с самим узлом.

Затем вы просто напишете два метода сравнения: один сравнивает по стоимости, а другой по происхождению.


И чтобы вернуться к исходной проблеме, как написать компаратор, который считает ["a", "b", "aa"] отсортированным?

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

Таким образом, правильная форма, если предположить две строки:

bool compare(std::string const& lhs, std::string const& rhs) {
  if (lhs.length() < rhs.length()) { return true; }
  if (rhs.length() < lhs.length()) { return false; } // don't forget this
  return lhs < rhs;
}
26.04.2011
  • Спасибо! Ваше решение действительно помогло мне раскрыть и понять, в чем проблема, и напомнило мне о другом случае, о котором я забыл. 26.04.2011

  • 2

    Нашел следующий сегмент кода, который вызывал ошибку, а затем подумал о том, как работает моя перегруженная операция.

    template<class _Ty1, class _Ty2> inline
        bool _Debug_lt(_Ty1& _Left, _Ty2& _Right,
            _Dbfile_t _File, _Dbline_t _Line)
        {   // test if _Left < _Right and operator< is strict weak ordering
        if (!(_Left < _Right))
            return (false);
        else if (_Right < _Left)
            _DEBUG_ERROR2("invalid operator<", _File, _Line);
        return (true);
        }
    

    Рабочее решение таково (снова изменено благодаря комментариям, оставленным Матье М.)

    // overloaded comparision operators
    friend bool operator<(const nodeRecord & record1, const nodeRecord & record2){
        // we need to deal with strings of different lengths...
        if(record1.comparator.length() > record2.comparator.length()
            && (record1.comparator.length() !=0 && record2.comparator.length() != 0))
            return false;
        else if(record1.comparator.length() < record2.comparator.length()
            && (record1.comparator.length() !=0 && record2.comparator.length() != 0))
            return true;
        else
            return (record1.comparator < record2.comparator);
    }
    

    Спасибо всем, кто помог!

    26.04.2011

    3

    Почему бы вам не использовать один компаратор и не сделать эту функцию немного умнее? Попросите его проверить числовые символы в начале, если да, выполните пару strtol() или atoi() и сравните результаты.

    В противном случае сравните длину строки и символы в соответствии с вашими нечисловыми требованиями.

    26.04.2011
  • Я хочу иметь возможность сортировать строки так же, как я сортирую числа. Например, строки a, aa и b должны быть отсортированы как a, b, aa. Метод, который я опубликовал, является единственным известным мне методом, который позволит мне это сделать. 26.04.2011
  • К сожалению, это не решит мою проблему. Такая же ошибка будет =( 26.04.2011
  • @BSchlinker: мой ответ предполагает использование только одной функции operator<, хотя она будет намного сложнее, чем ваша. 26.04.2011
  • Новые материалы

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

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

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

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

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

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

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