C ++: Как алфавитировать вектор строк без использования функции сортировки из библиотеки алгоритмов - PullRequest
1 голос
/ 17 апреля 2020

У меня есть вектор строк, где все строки были преобразованы в верхний регистр, чтобы их можно было сравнивать. Мне нужно использовать для циклов, чтобы алфавитно мой вектор. Мне нужно алфавитировать существующий вектор, а не создавать новый. Это определение моей функции:

void alpha(vector <string>& words){
    int minPos;
    int i = 0;
    for (i = 0; i < words.size(); i++) {
        minPos = i;
        for (int k = i + 1; k < words.size(); k++) {
            if (words.at(i) < words.at(k)) {
                minPos = k;
            }
        }
        }
        string temp = words.at(minPos);
        words.at(minPos) = words.at(i);
        words.at(i) = temp;
}

Вот ошибка, которую я сейчас получаю в main. cpp при вызове этой функции:

libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: vector

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

Ответы [ 2 ]

2 голосов
/ 17 апреля 2020

Вы выполняете операцию обмена после завершения i l oop, где i теперь установлено на words.size(). Поскольку допустимые индексы имеют значения от 0 до words.size() - 1 включительно, это приводит к возникновению ошибки за пределами допустимого диапазона.

Вам необходимо переместить операцию подкачки в внутри , что l oop :

void alpha(vector <string>& words) {
    // For each possible position in the collection.

    for (int i = 0; i < words.size(); ++i) {
        // Locate next lowest element (it should be in that position).

        int minPos = i;
        for (int k = i + 1; k < words.size(); ++k) {
            if (words.at(minPos) < words.at(k)) {
                minPos = k;
            }
        }

        // If not already there, swap it with what is there.

        if (i != minPos) {
            string temp = words.at(minPos);
            words.at(minPos) = words.at(i);
            words.at(i) = temp;
        }
    }
}

Вы также увидите несколько других улучшений:

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

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

std::sort (words.begin(), words.end());

И только одна небольшая нота Вы используете переменную minPos, но ваш реальный код сравнения отсортирует массив от наибольшего к наименьшему. Поэтому вам следует назвать это maxPos или изменить сравнение на противоположный смысл (сортировку от наименьшего к наибольшему с помощью >).


(a) Так что очевидно без учителей: -)

1 голос
/ 17 апреля 2020

Ваш отступ вводит в заблуждение.

Это более обычный отступ:

void alpha(vector <string>& words){
    int minPos;
    int i = 0;
    for (i = 0; i < words.size(); i++) {
        minPos = i;
        for (int k = i + 1; k < words.size(); k++) {
            if (words.at(i) < words.at(k)) {
                minPos = k;
            }
        }
    }
    string temp = words.at(minPos);
    words.at(minPos) = words.at(i);
    words.at(i) = temp;
}

, где вы можете видеть, что своп находится не внутри l oop, где он должен быть , но снаружи.
А после внешнего l oop, i равно words.size().

В качестве примечания, если вы объявили i в его l oop, как вы с k, это было бы ошибкой компиляции, и ее было бы намного легче обнаружить.

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