c++ - 如何实现 "InterpolatedVector"?

标签 c++ algorithm vector iterator

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

的 vector
1 / 2 / 3 / 4 

我想访问以下值

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

当然我不必存储这个中间值(简单的线性插值,我不必经常读取它们),所以我写了这个简单的类:

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::algorithms 一起使用,而且我没有迭代器。 (当然,我不能写中间值,但至少在阅读时,我想使用算法。)我应该指出,我对迭代器之类的东西仍然缺乏一点理解。

我应该如何实现这个“InterpolatedVector”,以便我可以做类似的事情

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

?

最佳答案

鉴于您已经拥有处理索引本身的代码,将其包装为迭代器非常容易。如果您能原谅我,我也会让它更通用一些。

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

...和一些快速演示代码来测试它:

#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::sort 没有多大意义(您显然需要对底层容器进行排序)。只要算法只需要读取数据,这应该没问题。

关于c++ - 如何实现 "InterpolatedVector"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29170935/

相关文章:

algorithm - 这个 String 可以通过洗牌这两个来创建吗?

使用列表类和 push_back 的 C++ 内存泄漏

c++ - 为什么通过指针交换在 C++ 中的 vector 中不起作用?

c++ - Rcpp map /字典/列表

C++:有什么方法可以防止抽象基类的任何实例化?

c++ - C++ 中 'isa' 的技术方面

c++ - 分而治之数组算法C++

java - 如何生成需求,使用单例进行数据库连接的优缺点?

c++ - 问题将对象插入 vector

c++ - 如何将 c++ 接口(interface) cv::Mat 转换为 c IplImage?