Сравнение строк в qsort

Всякий раз, когда я сравниваю строку в qsort, порядок совершенно неправильный. Например, вход

45 4 9 22 2

но мой вывод

22 45 4 9 2

вот моя функция сравнения

int cmpString(const void *a, const void *b) {
  const Node *a1 = *(const Node **)a;
  const Node *b1 = *(const Node **)b;

  return a1->s.c_str() - b1->s.c_str();
}

и не говорите мне использовать sort(), я не могу выполнить это задание


person jordan neely    schedule 07.02.2019    source источник
comment
Ярлык: std::string::compare.   -  person user4581301    schedule 07.02.2019
comment
и не говорите мне использовать sort() -- Стандарт говорит вам, что это поведение undefined. Посмотрите это и обратите внимание на этот отрывок: Тип элементы массива должны быть TrivialType, иначе поведение не определено. -- Скажите своему учителю, чтобы он взглянул и обдумал то, чему вас учат. Если вы вызываете qsort для массива std::string, то ваш код не работает, независимо от того, приняли ли вы данные ответы.   -  person PaulMcKenzie    schedule 07.02.2019
comment
Массив нетривиальных типов тоже никуда не годится. Итак, если Node — нетривиальный тип, то qsort использовать нельзя, независимо от ограничений, наложенных на вас учителем. Никакая программа на C++ не должна использовать qsort, если только нет чего-то лучшего в использовании qsort (с оговоркой, что это работает только для нетривиальных типов).   -  person PaulMcKenzie    schedule 07.02.2019


Ответы (1)


Эта строка является основной проблемой вашего кода.

return a1->s.c_str() - b1->s.c_str();

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

Вместо этого попробуйте следующее:

int length1 = a1->s.size();
int length2 = b1->s.size();

for (int i = 0; i < min(length1, length2); i++) {
    if (a1->s[i] != b1->s[i]) { // if characters are not same, return difference of their ASCII values.
        return a1->s[i] - b1->s[i];
    }
}

return length1 - length2; // if they are same till now, then shorter string should appear first. That's why it is required.

Предложение:

Если вы программируете на C++, используйте STL. Есть хорошая функция sort(), предоставленная <algorithm>, которая позволяет вам делать то же самое, не используя void *.

Обновление:

Как справедливо предложил user4581301, вы можете использовать std::string::compare напрямую.

Так:

return (a1->s).compare(b1->s);
person Kunal Puri    schedule 07.02.2019
comment
Вот оно! Действительно ценю это. - person jordan neely; 07.02.2019
comment
@jordanneely Если вы считаете, что это действительно ответило на ваш вопрос, рассмотрите возможность голосования и принятия. stackoverflow.com/help/someone-answers - person Kunal Puri; 07.02.2019
comment
Если вы используете qsort в массиве std::string или в структуре/классе, содержащем член std::string, забудьте об этом. Поведение не определено. - person PaulMcKenzie; 07.02.2019
comment
@PaulMcKenzie Вы уверены? См. stackoverflow.com/a/18929285/5859925. - person Kunal Puri; 07.02.2019