Изменить определенное значение при обнаружении изменения вектора - PullRequest
0 голосов
/ 05 декабря 2018

Итак, у меня есть следующий вектор:

vector<int> vec = {2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9};

У меня есть смещение значения, которое начинается с 0:

int offset = 0;

Я хочу пройти через массив и изменить смещениезначение соответственно.Например, если мы начали в начале (в первых 2), я хочу

offset = 0;

А затем, когда он прибывает во вторые 2, я хочу

offset = -16;

Но раз я вижу, что значение массива больше не равно 2 (оно изменяется), я хочу, чтобы смещение сбрасывалось до 0 (а затем, если оно увидит следующие 3, оно станет offset = offset - 16).

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

Каков наилучший способ сделать это?

Ответы [ 4 ]

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

Вот как я могу обобщить эту проблему:

  1. Передать ее функции по ссылке
  2. Проверить, является ли вектор пустым, если он есть, выдать исключение
  3. Имеет цикл for и объявляет offset вне , так что вы можете вручную сбросить offset, когда захотите.

Пример реализации:

#include <iostream>
#include <vector>
#include <stdexcept>

void gen_offset(const std::vector<int>& vec) {
    if (vec.empty()) {
        throw std::runtime_error("Vector is empty");
    }
    int offset = 0;
    int curr_val = vec[0];
    for (size_t i = 1; i != vec.size(); ++i) {
        if (vec[i] == curr_val) {
            offset -= 16;
        }
        else {
            std::cout << curr_val << " => " << offset << std::endl;
            offset = 0;
            curr_val = vec[i];
        }
    }
}

int main() {
    std::vector<int> vec = {2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
                       5, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9};
    gen_offset(vec);
    return 0;
}

Выход:

2 => -16
3 => -32
4 => -96
5 => 0
6 => -16
8 => -176
0 голосов
/ 05 декабря 2018

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

auto offset = 0;

cout << offset << ' ';
adjacent_find(cbegin(vec), cend(vec), [&](const auto lhs, const auto rhs){
    if(lhs == rhs) {
        offset -= 16;
    } else {
        offset = 0;
    }
    cout << offset << ' ';
    return false;
});

Live Example

0 голосов
/ 05 декабря 2018
#include <vector>
#include <iostream>

int Test(const std::vector<int> &vec)
{
    int offset = 0;
    int previous = vec.size() > 0 ? vec[0] : 0;
    for (auto &current : vec)
    {
        if (previous == current) offset -= 16;
        else offset = 0;
        previous = current;
    }
    return offset;
}


int main(int, char*[])
{
    std::cout << "None " << Test({}) << "\n";
    std::cout << "One " << Test({ 9 }) << "\n";
    std::cout << "Two Equal " << Test({ 9, 9 }) << "\n";
    std::cout << "Two Differnt " << Test({ 9, 8 }) << "\n";
    std::cout << "Many " << Test({ 2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9 }) << "\n";
    return 0;
}

Чтобы найти лучшее решение для вас, вам следует попробовать протестировать любое решение, которое вы создаете, чтобы убедиться, что оно работает так, как вам нужно.Вывод этого фрагмента может быть проверен, и вы можете проверить отдельные тесты с помощью отладчика.Подумайте об использовании инфраструктуры тестирования, чтобы сохранить тесты на будущее.

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

Это то, что вы объясняете словами, переведенными в код:

vector<int> vec = {2, 2, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9};
int offset = 0;
int current = vec[0];
for (unsigned i = 1; i< vec.size(); ++i) {
     if (vec[i] == current) offset -= 16;
     else                   offset = 0;
     current = vec[i];
 }

Хотя я не совсем понимаю, для чего это должно быть хорошо, или что вы имеете в виду под «лучшим способом».Тем не менее, код был слишком много для комментария ....

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