Проблема с сортировкой векторных строк с помощью std :: sort () с использованием настраиваемой функции сравнения - PullRequest
1 голос
/ 09 июля 2020

Я пытаюсь отсортировать строки в соответствии с правилом. Код C ++ работает в большинстве случаев, но в некоторых случаях выдает ошибку:

  terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid

Я видел эту ошибку раньше, это происходит, когда мы пытаемся инициализировать строку как нулевой указатель или 0 (который внутренне преобразован как нулевой указатель). Я проверил, что ошибка возникает во время сортировки и только тогда, когда я использую настраиваемую функцию для сравнения. Еще раз, я не знаю, почему это происходит только в определенных случаях.

Код:

#include <algorithm>
#include <sstream>
#include <iostream>
#include <vector>
#include <string>

using std::vector;
using std::string;

bool greater(string a, string b) {
  int i = 0;
  a = a + a[0];
  b = b + b[0];
  while(i<a.size() && i<b.size()) {
    if(a[i] != b[i]) {
      if(a[i] - '0' > b[i] - '0')
      return true;
      else return false;
    }
    i++;
  }
  
}

string largest_number(vector<string> a) {
  std::sort(a.begin(), a.end(), greater);
  std::stringstream ret;
  for (size_t i = 0; i < a.size(); i++) {
    ret << a[i];
  }
  string result;
  ret >> result;
  return result;
}

int main() {
  int n;
  std::cin >> n;
  vector<string> a(n);
  for (size_t i = 0; i < a.size(); i++) {
    std::cin >> a[i];
  }
  std::cout << largest_number(a);
  return 0;
}

Один из случаев, когда он выдает ошибку:

100  
2 8 2 3 6 4 1 1 10 6 3 3 6 1 3 8 4 6 1 10 8 4 10 4 1 3 2 3 2 6 1 5 2 9 8 5 10 8 7 9 6 4 2 6 3 8 8 9 8 2 9 10 3 10 7 5 7 1 7 5 1 4 7 6 1 10 5 4 8 4 2 7 8 1 1 7 4 1 1 9 8 6 5 9 9 3 7 6 3 10 8 10 7 2 5 1 1 9 9 5

РЕШЕНИЕ: Спасибо за помощь. Ошибка возникла, поскольку функция сравнения ничего не возвращала после выхода из l oop. Вот обновленная функция, которая работает.

bool greater(string a, string b) {
  int i = 0;
  a = a + a[0];
  b = b + b[0];
  while(i<a.size() && i<b.size()) {
      if(a[i] > b[i])
        return true;
    i++;
  }
  return false; 
}

1 Ответ

3 голосов
/ 09 июля 2020

Единственная проблема, которую я вижу с кодом (на самом деле я пробовал использовать онлайн-компилятор, и он дал мне это предупреждение), это то, что вы ничего не возвращаете из greater, если две строки равны:

bool greater(string a, string b) {
  int i = 0;
  a = a;
  b = b;
  while(i<a.size() && i<b.size()) {
    if(a[i] != b[i]) {
      if(a[i] - '0' > b[i] - '0')
      return true;
      else return false;
    }
    i++;
  }
  // <---- what about here?
}

Попробуйте вставить оператор возврата. (Конечно, если две вещи равны, то ни одна из них не превосходит другую, поэтому, в частности, это return false, который вам нужен.) Падение конца функции без оператора return - это поведение undefined (кроме int main() или любой функции, возвращающей void), так что вы можете ожидать увидеть что-нибудь вообще, когда это произойдет, включая тип полученного cra sh.

[Изменить: как gst говорит, что вы также попадаете в эту точку, если одна строка является префиксом другой, например, "1" и "10". Так что вам понадобится немного больше кода для тестирования, а не просто return false. Но вы могли видеть, исправит ли эта одна строка ошибку cra sh: это было бы логически неверным, но, по крайней мере, не неопределенным поведением.]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...