Как я могу напечатать вектор в рекурсивной функции?

Вы также можете построить парную метку, пары значений, используя pyplot.plot (после разбора их из строкового представления). (Протестировано с версиями matplotlib 1.2.0 и 1.3.1.)

Пример:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.plot(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

Результирующее изображение:

Line Plot [/g2]


Вот то же самое, что и график рассеяния:

import datetime
import random
import matplotlib.pyplot as plt

# make up some data
x = [datetime.datetime.now() + datetime.timedelta(hours=i) for i in range(12)]
y = [i+random.gauss(0,1) for i,_ in enumerate(x)]

# plot
plt.scatter(x,y)
# beautify the x-labels
plt.gcf().autofmt_xdate()

plt.show()

Производит изображение, подобное этому:

1
задан Syfu_H 30 March 2019 в 23:12
поделиться

4 ответа

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

void print(const std::vector<int>& ivec, std::vector<int>::const_iterator it) {
    if (it == ivec.end())
        return;
    std::cout << *it++ << std::endl;
    print(ivec, it);
}

int main(){
    vector<int> v{
        5, 7, 77, 23, 10, 81
    };

    print(v, v.begin()); // ok

    vector<int>::iterator it = v.begin();
    auto v2{ v };

    if (it == v.begin())
        cout << "it = v.begin()" << endl;
    if (it == v2.begin()) // causes crash
        cout << "it =v2.begin()" << endl;
}
0
ответ дан Raindrop7 30 March 2019 в 23:12
поделиться

Когда вы звоните print, вы передаете вектор по значению. Это означает, что он каждый раз создает совершенно новый вектор, но итератор все еще исходит из исходного вектора. Поскольку итератор происходит из другого вектора, тест it == ivec.end() всегда будет неудачным.

Мы можем это исправить, просто передав ivec константную ссылку:

void print(const std::vector<int>& ivec, std::vector<int>::const_iterator it) 
{
    if (it == ivec.end())
        return;
    std::cout << *it++ << std::endl;
    print(ivec, it);
}

И код работает отлично!

0
ответ дан J. Antonio Perez 30 March 2019 в 23:12
поделиться
void print(const std::vector<int> ivec, std::vector<int>::const_iterator it) {

Параметр ivec передается по значению. Оба эти параметра передаются по значению. Передача по значению означает, что внутри функции это копий исходных параметров.

Ваш main() вызывает эту рекурсивную функцию, передавая ей свой вектор и начальный итератор своего вектора. Однако, поскольку все параметры передаются по значению, каждая рекурсивная итерация функции сравнивает итератор с end() совершенно другого вектора. Неопределенное поведение.

Вы, очевидно, забыли передать вектор по ссылке. Первый параметр должен быть const std::vector<int> &ivec.

0
ответ дан Sam Varshavchik 30 March 2019 в 23:12
поделиться

Нет необходимости передавать два аргумента функции печати. Если вектор нулевой длины, ничего не печатать.

Если вектор имеет длину 1, выведите этот элемент.

Если вектор имеет длину больше 1, выведите меньший вектор (рекурсивно), который не содержит последний символ, а затем напечатайте последний символ.

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

#include <iostream>
#include <vector>

void print(const std::vector<int> vec) {
    if (!vec.size())
        return; 
    else {
        print(std::vector<int>(vec.begin(), vec.end() - 1));
        std::cout << " " << *(vec.end() - 1);
    }
}

int main(){

    std::vector<int> v{
            5, 7, 77, 23, 10, 81
    };

    print(v);
}
0
ответ дан Gardener 30 March 2019 в 23:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: