按索引从周期序列 0,1,2,3,2,1,0,1... 获取值的最简单方法是什么?
what is the simplest way to get the value from periodic sequence 0,1,2,3,2,1,0,1... by index?
例如,我有一个周期序列从 0 开始,然后是 1,2,直到 3,然后开始下降到 2,1,然后是 0,然后又是 1。设函数为 f(min,max,x),其中 x 是索引,所以:
f(0,3,0)=0
f(0,3,1)=1
f(0,3,2)=2
f(0,3,3)=3
f(0,3,4)=2
.
.
.
f(0,3,9)=3
我试过类似的方法:
public static int f(int min,int max,int x){
int r=min;
int increment=1;
for(int i=0;i<x;i++){
if(r==max){
increment=-1;
}else if(r==min){
increment=1;
}
r+=increment;
}
return r;
}
但我觉得它很长而且效率低下,有没有更简单的方法来实现f(min,max,x)?
或者只用一行就可以完成,比如 int result=(some +-*/,mod,trinary operator... to min,max,x)?
int index = x % (2*(max-min)); // take care of periodicity
int val = 0;
if(index <= max){ // first half cycle
val = index
}else{ // second half cycle
val = 2 * max - index
}
return min + val // add min
这个逻辑对于你想做的应该是正确的。
int f(int min, int max, int x) {
const int len = (max - min) * 2;
const int offset = (x + len - 1) % len;
const int ans = (offset + 1) % len;
return min + ans > max ? min + len - ans : min + ans;
}
检查一下live here
作为显式公式的解决方案:
// note this doesn't work for negative values as expected
public static int f(int min,int max,int x) {
return max-abs(x%((max-min)*2)-max+min)
}
// just add abs(x) to make it work for negative numbers
public static int f(int min,int max,int x) {
return max-abs(abs(x)%((max-min)*2)-max+min)
}
例如,我有一个周期序列从 0 开始,然后是 1,2,直到 3,然后开始下降到 2,1,然后是 0,然后又是 1。设函数为 f(min,max,x),其中 x 是索引,所以:
f(0,3,0)=0
f(0,3,1)=1
f(0,3,2)=2
f(0,3,3)=3
f(0,3,4)=2
.
.
.
f(0,3,9)=3
我试过类似的方法:
public static int f(int min,int max,int x){
int r=min;
int increment=1;
for(int i=0;i<x;i++){
if(r==max){
increment=-1;
}else if(r==min){
increment=1;
}
r+=increment;
}
return r;
}
但我觉得它很长而且效率低下,有没有更简单的方法来实现f(min,max,x)?
或者只用一行就可以完成,比如 int result=(some +-*/,mod,trinary operator... to min,max,x)?
int index = x % (2*(max-min)); // take care of periodicity
int val = 0;
if(index <= max){ // first half cycle
val = index
}else{ // second half cycle
val = 2 * max - index
}
return min + val // add min
这个逻辑对于你想做的应该是正确的。
int f(int min, int max, int x) {
const int len = (max - min) * 2;
const int offset = (x + len - 1) % len;
const int ans = (offset + 1) % len;
return min + ans > max ? min + len - ans : min + ans;
}
检查一下live here
作为显式公式的解决方案:
// note this doesn't work for negative values as expected
public static int f(int min,int max,int x) {
return max-abs(x%((max-min)*2)-max+min)
}
// just add abs(x) to make it work for negative numbers
public static int f(int min,int max,int x) {
return max-abs(abs(x)%((max-min)*2)-max+min)
}