当我检测到向量变化时更改某些值

时间:2018-12-05 12:37:45

标签: c++ vector

所以,我有以下向量:

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(它会更改),我想将offset重置为0(然后如果看到下一个3,它将变成offset = offset - 16)。

我想从偏移值中减去16,只要向量在迭代时不改变即可。但是一旦检测到更改,我想重置偏移量。

做到这一点的最佳方法是什么?

4 个答案:

答案 0 :(得分:1)

这就是您用翻译成代码的单词所解释的内容:

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];
 }

尽管我不太了解这应该有什么好处,或者您所说的“最佳方式”是什么意思。但是,该代码太多了,无法发表评论。...

答案 1 :(得分:1)

#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;
}

要找到最适合您的解决方案,您应该考虑测试您创建的任何解决方案,以便知道它具有所需的行为。可以检查此代码段的输出,您可以使用调试器检查各个测试。考虑使用测试框架保留将来的测试。

答案 2 :(得分:0)

目前尚不清楚您想使用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

答案 3 :(得分:0)

这是我概括这个问题的方法:

  1. 通过引用将其传递给函数
  2. 检查向量是否为空,如果为空,则引发异常
  3. 具有一个for循环,并在其外部{strong>声明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