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

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

问题描述

我有一个的std ::矢量<双> ,我需要插自己的价值观。例如,只有1个中间值,并给出充满了一个vector

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 

我要访问以下值

I want to access the following values

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? */ );

推荐答案

既然你已经有了code来处理索引本身,包装,作为一个迭代器pretty的方便。如果你能原谅我,我也要去,使之更有点普通。

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

...和演示code快一点来测试它:

...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

当然,一些算法仍然不能够做很多与这类收藏的。试图养活插集合的std ::排序就没有太大的意义(你显然需要底层的容器进行排序)。只要算法只需要读取数据,这应该是罚款,但。

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.

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

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