Отображение функции на вектор рекурсивно - PullRequest
0 голосов
/ 25 января 2019

У меня есть класс с именем mapTriple, который имеет метод, который принимает целочисленный вектор и умножает все значения в векторе на частную функцию класса mapTriple (функция принимает целое число и возвращает целое число * 3)

Я уже настроил классы и функцию, которая утраивает целое число. Я застрял на методе mapTriple. Метод не может быть итеративным, он должен быть рекурсивным.

vector<int> MapTriple::map(vector<int> myVector)
{
    if(myVector.size() == 1)
    {
        myVector[0] = f(myVector[0]);
        return myVector;
    }
    else
    { 
        map(myVector.erase(myVector.begin()+myVector.size()-1));
        myVector[myVector.size()-1] = f(myVector[myVector.size()-1]);
        return myVector;
    }

}

int f (int a)
{
    return (a*3);
}

В настоящее время он не компилируется, он говорит, что нет соответствующего вызова для карты. У меня есть все .h файлы и основные файлы и т. Д.

1 Ответ

0 голосов
/ 25 января 2019

erase не возвращает измененный вектор. Он возвращает итератор после удаленного элемента (который в вашем случае будет end, так что вам это не нужно). Просто передайте измененный вектор сам.

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

Правильная ветка else должна быть:

else
{
    // Store and remove the last element.
    int currentElement = myVector.back();
    myVector.erase(myVector.end()-1);
    // Recursively process the remaining elements.
    map(myVector);
    // Process and re-add the above element.
    myVector.push_back(f(currentElement));
    return myVector;
}

Однако вместо стирания элементов и их повторного добавления вы можете работать с итераторами.

using Iterator = std::vector<int>::iterator;

void MapTriple::map(Iterator start, Iterator end)
{
    // No elements remaining?
    if (start == end)
      return;

    // Process first element.
    *start = f(*start);

    // Process remaining elements recursively.
    map(start+1, end);
}

Хотя это довольно элегантно, было бы, конечно, еще проще сделать это с помощью простого цикла for:

for (auto& e : myVector) e = f(e);  

или std::transform:

std::transform(myVector.begin(), myVector.end(), myVector.begin(),
               [this](int e) -> { return f(e); });`

Следует также отметить, что map, вероятно, является посредственным именем для этого метода, если вы сделали using namespace std;, как кажется, имеет место (см. Также Почему "использование пространства имен std" считается плохой практикой? ).

...