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

#include <bits/stdc++.h>
#include <vector>
using namespace std;

// Function to print permutations of string
// This function takes three parameters:
// 1. String
// 2. vector to store string permutation
// 3. dummy vector to store each permutation
vector<vector<int> > permute(vector<int> nums, vector<vector<int> >& k, vector<int> li)
{
    if (nums.empty()) {
        k.push_back(li);
    }
    else {
        for (int i = 0; i < nums.size(); i++) {
            int chos = nums[i];
            li.push_back(chos);
            nums.erase(nums.begin() + i);
            permute(nums, k, li);
            nums.insert(nums.begin() + i, chos);
            li.erase(li.end()-1);
        }
    }
    return k;
}

// Driver Code
int main()
{
    vector<int> permut = { 1, 2, 3 };
    vector<vector<int> > k;
    vector<int> li;

    k = permute(permut, k, li);
    return 0;
}
0
devss 27 Окт 2019 в 05:54
3
#include <bits/stdc++.h> -- Используйте правильные файлы заголовков, а не этот.
 – 
PaulMcKenzie
27 Окт 2019 в 06:08
Что такое трассировка стека в дампе ядра?
 – 
Thomas Sablik
27 Окт 2019 в 06:11
Когда вы отлаживали эту программу, в какой строке вы видели ошибку сегментации?
 – 
JaMiT
27 Окт 2019 в 06:12
2
li.erase(li.end()); -- Что вы пытаетесь здесь сделать?
 – 
PaulMcKenzie
27 Окт 2019 в 06:14
Пожалуйста, отформатируйте свой код в будущем. Если ваша IDE не поддерживает его, вы можете использовать format.krzaq.cc.
 – 
Thomas Sablik
27 Окт 2019 в 06:15

1 ответ

что не так с кодом?

Одна вещь, безусловно, неправильная в коде, это эта строка:

li.erase(li.end());

Вы вызываете erase на итераторе end(), что является неопределенным поведением.

Если вы хотите удалить последний символ, правильный способ сделать это:

if ( !li.empty())
    li.erase(std::prev(li.end(), 1));
0
PaulMcKenzie 27 Окт 2019 в 06:33
Почему prev(li.end(), 1)? li.end() - 1 подходит, или хотя бы prev(li.end()).
 – 
L. F.
27 Окт 2019 в 06:39
Ответ работает для любого контейнера, а не только для вектора.
 – 
PaulMcKenzie
27 Окт 2019 в 06:41
Тогда почему бы не использовать шаблон и SFINAE для поддержки всех контейнеров? Способ вывода результирующих последовательностей также можно отсортировать на основе настраиваемых критериев с помощью итератора вывода. Во всяком случае, AFAIK, prev(li.end()) всегда эквивалентен prev(li.end(), 1).
 – 
L. F.
27 Окт 2019 в 06:44
Спасибо, но когда я отлаживаю код, он неправильно возвращает вектор перестановки строк li в вектор k (вектор для хранения всей строки перестановок), он возвращает только первую перестановку строк. как я могу его сохранить?
 – 
devss
27 Окт 2019 в 06:47
-- Ваш вопрос касался ошибки сегментации, на которую, я думаю, был дан ответ. Ваша программа, выдающая неправильный вывод, — это отдельная история, и вам нужно отладить свой код.
 – 
PaulMcKenzie
27 Окт 2019 в 06:49