这是一个有趣的问题,但更多的是关于算法而不是数据结构。
我注意到Map^i[n] 可以在恒定时间内解决...如果您调整访问而不是修改结构。
根据我对问题的理解,这些值只是“循环”:[15, 20, 12, 18] -> [20, 12, 18, 15] -> [12, 18, 15, 20] -> [18, 15, 20, 12]
公式:
- 令 N 为序列的大小 -
[0, N] 中的 1 和 n 为序列中的索引
- 让
[0, N] 中的 i 成为一个迭代
Value^i[n] = Value[n+i%(N+1)]
但是键是不同的:
-
[0.5, 1, 2.3, 3.7] -> [0.5, 1.8, 3.2, 3.7] -> [1.3, 2.7, 3.2, 3.7] -> [1.4, 1.9, 2.4, 3.7]
- 让我们试着看看一个模式:
[a, b, c, d] -> [b-a, c-a, d-a, d] -> [c-b, d-b, d-b+a, d] -> [d-c, d-c+a, d-c+b, d]
让图案更明显:
0: [a , b , c , d , e , f]
1: [b-a , c-a , d-a , e-a , f-a , f]
2: [c-b , d-b , e-b , f-b , f-(a-b), f]
3: [d-c , e-c , f-c , f-(a-c), f-(b-c), f]
4: [e-d , f-d , f-(a-d), f-(b-d), f-(b-e), f]
5: [f-e , f-(a-e), f-(b-e), f-(c-e), f-(d-e), f]
请注意,这在某种程度上也是循环,因为再次应用转换将产生原始序列。
公式(我们重用之前的变量):
Key^i[n] = | n = N => Key[N]
| i = 0 => Key[n]
| n <= N-i => Key[n+i] - Key[i-1]
| n > N-i => Key[N] - (Key[n+i % (N+1)] - Key[i-1])
如果我们(任意)定义Key[-1] = 0,后3行可以聚合在(Key[n+i % (N+1)] - Key[i-1]) % Key[N]中。
现在我们有了公式,我们需要一个随机访问的结构,我将简单地选择一个vector。
下面提供的可编译示例(或参见ideone)给出:
[ 0.5: 15, 1: 20, 2.3: 12, 3.7: 18 ]
[ 0.5: 20, 1.8: 12, 3.2: 18, 3.7: 15 ]
[ 1.3: 12, 2.7: 18, 3.2: 15, 3.7: 20 ]
[ 1.4: 18, 1.9: 15, 2.4: 20, 3.7: 12 ]
例子:
#include <cassert>
#include <algorithm>
#include <iostream>
#include <vector>
typedef std::pair<double, double> Pair;
typedef std::vector<Pair> Vector;
double key(Vector const& vec, size_t const i, size_t const n) {
assert(n < vec.size() && "Wrong index");
if (i == 0) { return vec[n].first; }
size_t const N = vec.size() - 1;
if (n == N) { return vec.back().first; }
double const partial = vec[(n+i) % (N+1)].first - vec[(i-1) % (N+1)].first;
return (n <= N-i) ? partial : partial + vec[N].first;
} // key
double value(Vector const& vec, size_t const i, size_t const n) {
assert(n < vec.size() && "Wrong index");
return vec[(n+i) % vec.size()].second;
} // value
int main() {
Vector vec{ Pair(0.5, 15), Pair(1, 20), Pair(2.3, 12), Pair(3.7, 18) };
sort(vec.begin(), vec.end()); // just to be sure
size_t const size = vec.size();
for (size_t i = 0; i != size; ++i) {
std::cout << "[ ";
for (size_t n = 0; n != size; ++n) {
if (n != 0) { std::cout << ", "; }
std::cout << key(vec, i, n) << ": " << value(vec, i, n);
}
std::cout << " ]\n";
}
}