摇摆序列

来源:互联网 发布:网络上 求gm什么意思 编辑:程序博客网 时间:2024/04/30 07:41

无穷序列千奇百怪,常见的却寥寥可数.除自然数序列与斐波那契序列外,以下两个序列十分常见:

  • 循环序列: 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, …
  • 摇摆序列: 0, 1, 2, 3, 2, 1, 0, 1, 2, 3, 2, ,1, 0, …

对于循环序列,我们有很优雅的生成方式:

for(i = 0; ;++i)    printf("%d, ", i%4);

但是对于摇摆序列,生成方式却要复杂一些.例如,我们可以用下面的循环生成一个摇摆序列:

void swing(void) {    int i = 0, d = 1;    while (true) {        printf("%d, ", i);        getchar();        if (i == 3)            d = -1;        else if (i == 0)            d = 1;        i += d;    }}

注意这里不能将两个if语句合为一个,写成这样:

if (i == 0 || i == 3)    d *= -1

因为当你将这个函数的参数分离出来的时候,若给定初值为0,d为1,那么这段代码将会崩溃.

更一般地,可以将摇摆序列抽象成一个类:

struct Swinger {    int left, rght;    int curr, step;    Swinger(void) {        range(0, 0);        ready(0, 0);    }    Swinger(const int left, const int rght, const int bgn=0, const int step=0) {        range(left, rght);        ready(bgn, step);    }    /** 设定摇摆范围 */    inline void range(const int left, const int rght) {        this->left = left;        this->rght = rght;    }    /** 设置摇摆的初值和方向 */    inline void ready(const int bgn, const int step) {        curr = bgn;        this->step = step;    }    /** 取摇摆序列中的下一个值     *     * 必须设定好摇摆区间和摇摆的初值与方向     */    inline int next(void) {        int res = curr;        if (curr <= left)            step = abs(step);        else if (curr >= rght)            step = -1 * abs(step);        curr += step;        return res;    }    /** 用摇摆序列填充一个数组 */    void fill(int * const a, const int n, const int bgn, const int step) {        ready(bgn, step);        for (int i = 0; i < n; ++i)            a[i] = next();    }};

然后,你可以用这种方式取调用这个类:

int main(void) {    int a[100];    Swinger swinger;    swinger.range(0, 5);    swinger.ready(0, -1);    for (int i = 0; i < 100; ++i)        printf("%d, ", swinger.next());    printf("\n");    swinger.range(0, 15);    swinger.fill(a, 100, 0, 1);    for (int i = 0; i < 100; ++i)        printf("%d, ", a[i]);    printf("\n");}

值的注意的有3点:

  1. 一定要有意识地区分摇摆序列与循环序列
  2. 一个摇摆序列由4个参数唯一确定: 左端点,右端点,初值,初始方向
  3. 生成下一个摇摆序列中的元素之前,一定要用**两个**if语句判明方向
1 0