Исключение вектора и карты - PullRequest
0 голосов
/ 10 декабря 2018

моя задача - вывести все десятизначные числа, где числа не повторяются.И сначала я использую что-то вроде этого:

#include <cstdio>
#include <iostream>
#include <string>
#include <map>
#include <functional>

using namespace std;

void Task5() {
    auto initialization = [](map<int, bool> *m, int count) {
        for (int i = 0; i < 10; ++i)
            m[i] = true;
    };
 /*For cut duplicate number in map*/
    auto cutting = [](map<int, bool> *m, int count, int value) {
        for (int i = 9; i > count; --i)
            m[count][i][value] = false;
    };
 /*For create copy map*/
    auto mould = [](map<int,bool> *m, map<int, bool> *m_copy, int count) -> map<int, bool>* {
        if (m_copy == nullptr) {
            map<int, bool> *m_copy = new map<int, bool>[10 - count];
            for (int i = 9; i > count; --i)
                for (int j = 0; j < 10; ++j)
                    m_copy[i][j] = m[i][j]; /*<= here throw exepition*/
            return m_copy;
        }
        else {
            for (int i = 9; i > count; --i)
                for (int j = 0; j < 10; ++j)
                    m[i][j] = m_copy[i][j];
            return m;
        }
    };

    function<void(map<int, bool>*, int, int*)> recursive;
    recursive = [mould, cutting, &recursive](map<int, bool> *m, int count = 1, int *result = nullptr) -> void {
        if (count != 10) {
            for (int i = 0; i < 10; ++i) {
                static map<int, bool> *m_copy;
                if (i == 0)
                    m_copy = mould(m, nullptr, 1);
                else {
                    m = mould(m, m_copy, 1);
                    if (m[count][i])
                        result[count - 1] = i;
                    else
                        continue;
                }       
                cutting(m, count, i);
                recursive(m, ++count, result);
            }
            delete[] m_copy;
        }
        else {
            for (int i = 0; i < 10; ++i)
                cout << result[i];
            cout << endl;
        }
    };
     /*Create map
       int is digit(can be 0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
       if digit is used bool will be false*/
    map<int, bool> *m = new map<int, bool>[10];
    for (int i = 0; i > 10; ++i)
        initialization(m, i);
    m[0][0] = false; //First number cant' be 0
    int *result = new int[10];
    recursive(m, 1, result);
    delete[] m;
    delete[] result;
}

int main(){
    Task5();
    return 0;
}

Но он выбрасывает исключение std :: out_of_range.Теперь у меня есть look и map [0], размер 1, другая карта (map [1], map [2] и др.) Имеет размер 0. Почему это так?Поэтому я смотрю на форум и не могу найти ответ.Поэтому я решил переписать решение.И напишите что-то вроде этого:

#include <cstdio>
#include <iostream>
#include <string>
#include <map>
#include <functional>
#include <vector>

using namespace std;

auto end_task = []() {
    cout << endl << endl << endl;
};

void initialization(vector<bool> &vec) {
    vec.reserve(10);
    for (int i = 0; i < 10; ++i)
        vec[i] = true;
}

void cutting(vector<bool> *vec, int count, int value) {
    for (int i = 9; i > count; --i)
        vec[i][value] = false;
}

vector<bool> *mould(vector<bool> *vec, vector<bool> *vec_copy, int count) {
    if (vec_copy == nullptr) {
        vector<bool> *vec_copy = new vector<bool>[10 - count];
        for (int i = 9; i > count; --i)
            for (int j = 0; j < 10; ++j)
                vec_copy[i][j] = vec[i][j];
        return vec_copy;
    }
    else {
        for (int i = 9; i > count; --i)
            for (int j = 0; j < 10; ++j)
                vec[i][j] = vec_copy[i][j];
        return vec;
    }
}

void recursive(vector<bool> *vec, int count = 1, int *result = nullptr) {
    if (count != 10) {
        for (int i = 0; i < 10; ++i) {
            static vector<bool> *vec_copy;
            if (i == 0)
                vec_copy = mould(vec, nullptr, 1);
            else {
                vec = mould(vec, vec_copy, 1);
                if (vec[count][i])
                    result[count - 1] = i;
                else
                    continue;
            }
            cutting(vec, count, i);
            recursive(vec, ++count, result);
        }
        delete[] vec_copy;
    }
    else {
        for (int i = 0; i < 10; ++i)
            cout << result[i];
        cout << endl;
    }
}

void Task5() {
    vector<bool> *vec = new vector<bool>[10];
    for (int i = 0; i > 10; ++i)
        initialization(vec[i]);
    vec[0][0] = false;
    int *result = new int[10];
    recursive(vec, 1, result);
    delete[] m;
    delete[] result;
    end_task();
}


int main(){
    Task5();
    return 0;
}

(без лямбда-функции, потому что я начал их подозревать) Но здесь размер вектора равен 1 и 0. И у меня есть ошибка: векторный итератор не разыменовывается.Зачем?Где моя ошибка?

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Простой способ решить вашу проблему с STL - использовать std::next_permutation:

std::vector<int> digits{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; // Sorted

do
{
    for (auto d : digits) {
        std::cout << d;
    }
    std::cout << std::endl;
} while (std::next_permutation(digits.begin(), digits.end()));

Демо

0 голосов
/ 10 декабря 2018

Давайте посмотрим ближе на строку, где вы получаете исключение (вместе с некоторым контекстом):

map<int, bool> *m_copy = new map<int, bool>[10 - count];
for (int i = 9; i > count; --i)
    for (int j = 0; j < 10; ++j)
        m_copy[i][j] = m[i][j]; /*<= here throw exepition*/

В первой строке создайте совершенно новую переменную с именем m_copy (добавление к путанице, посколькуон скрывает лямбда-аргумент с тем же именем) и указывает на «массив» из 10 - count элементов.

Верхний индекс этого «массива» будет 10 - count - 1, который будет толькоравно 9, если count == 0.Это означает, что внешний цикл будет начинаться с недопустимого и за пределами индекса в любое время, когда count > 0.

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