如何实现“InterpolatedVector”? [英] How to implement a "InterpolatedVector"?

查看:120
本文介绍了如何实现“InterpolatedVector”?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 std :: vector< double> ,我需要插值它的值。例如只有一个中间值,并且给定一个向量填充

I have a std::vector<double> and I need to interpolate its values. For example with only 1 intermediate value and given a vector filled with

1 / 2 / 3 / 4 

我要访问以下值

1 / 1.5 / 2 / 2.5 / 3 / 3.5 / 4

不需要存储这个中间值(简单的线性插值,我不必太频繁地读取),所以我写了这个简单的类:

Of course I do not have to store this intermediate values (simple linear interpolation and I do not have to read them too often), so I wrote this simple class:

typedef std::vector<double> DVector;
class InterpolatedVector {
public:
    InterpolatedVector(const DVector& v,int steps) : v(v),steps(steps){}
    double at(int i){
        int j = i%steps;
        int k = (int)i/steps;
        if (i==0){return v[0];}
        else if (i==v.size()*steps){return v.back();}
        else {return  ((steps-j)*v[k] + j*v[k+1])/steps;}
    }
    int size(){return steps*(v.size()-1) + 1;}
private:
    DVector v;
    int steps;
};

它工作正常,我得到(几乎)我想要的。但是,这个容器我不能使用std ::算法,我没有迭代器。 (当然,我不能写中间值,但至少当它是关于阅读,我想使用算法)。我应该提到,我仍然缺乏对迭代器等了解一点。

It works fine and I get (almost) what I want. However, this "container" I cannot use with the std::algorithms and I do not have iterators for it. (Of course, I cannot write the intermediate values, but at least when it is about reading, I would like to use the algorithms.) I should mention that I am still lacking a bit of understanding on iterators and the like.

我应该如何实现这个InterpolatedVector,以便我可以做

std::accumulate(/* passing Interpolated iterators? */ );

推荐答案

由于已经有了处理索引本身的代码,所以将它作为迭代器包装起来很容易。如果你原谅我,我也会让它更通用。

Given that you already have the code to handle the indexing itself, wrapping that as an iterator is pretty easy. If you'll forgive me, I'm also going to make it a bit more generic.

#include <vector>
#include <iterator>

template <class T>
class InterpolatedVector {
    typedef std::vector<T> DVector;
public:
    InterpolatedVector(const DVector& v,int steps) : v(v),steps(steps){}
    T at(int i){
        int j = i%steps;
        int k = (int)i/steps;
        if (i==0){return v[0];}
        else if (i==v.size()*steps){return v.back();}
        else {return  ((steps-j)*v[k] + j*v[k+1])/steps;}
    }
    int size(){return steps*(v.size()-1) + 1;}

    class iterator : public std::iterator < std::random_access_iterator_tag, T > {
        InterpolatedVector *vec;
        int index;
    public:
        iterator(InterpolatedVector &d, int index) : vec(&d), index(index) {}
        iterator &operator++() { ++index; return *this; }
        iterator operator++(int) { iterator tmp{ *vec, index }; ++index; return tmp; }
        iterator operator+(int off) { return iterator(*vec, index + off); }
        iterator operator-(int off) { return iterator(*vec, index - off); }
        value_type operator*() { return (*vec).at(index);   }
        bool operator!=(iterator const &other) { return index != other.index; }
        bool operator<(iterator const &other) { return index < other.index; }
    };

    iterator begin() { return iterator(*this, 0); }
    iterator end() { return iterator(*this, size()); }
private:

    DVector v;
    int steps;
};

...和一个简单的演示代码来测试它:

...and a quick bit of demo code to test it out:

#include <iostream>

int main() {
    std::vector<double> d{ 1, 2, 3, 4 };
    InterpolatedVector<double> id(d, 2);

    std::copy(id.begin(), id.end(), std::ostream_iterator<double>(std::cout, "\t"));
    std::cout << "\n";

    std::vector<int> i{ 0, 5 };
    InterpolatedVector<int> ii(i, 5);

    std::copy(ii.begin(), ii.end(), std::ostream_iterator<int>(std::cout, "\t"));
}

输出:

1       1.5     2       2.5     3       3.5     4
0       1       2       3       4       5


b $ b

当然,一些算法仍然不能用这种集合做很多事情。尝试将插入的集合馈送到 std :: sort 将没有什么意义(你显然需要排序底层容器)。只要算法只需要读取数据,这应该很好。

Of course, some algorithms still won't be able to do much with this sort of "collection". Trying to feed an interpolated collection to std::sort wouldn't make much sense (you'd clearly need to sort the underlying container). As long as the algorithm only needs to read the data, this should be fine though.

这篇关于如何实现“InterpolatedVector”?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆