数组“之”字打印,状态机做法

这种方式比较好理解

原数组:

  0    1    2    3    4    5  
  6    7    8    9   10   11  
 12   13   14   15   16   17  
 18   19   20   21   22   23 

期待输出的数组:

  0    1    6   12    7    2    3    8   13   18   19   14    9    4    5   10   15   20   21   16   11   17   22   23

状态机的转换主要用于处理下一步的走法,这一个题目的复杂点只能是逐步走,不能上来就确定8位置是怎么走,没有动态规划的特征。只能是硬解:

比如0是起点:下一步向右,nextState=Right,  column++;

到1点 nextState = leftdown, 左下方向,row++,column--;

到6点newState = down, column=0, 无法--,只能向下走,column不变,row++;

。。。

到12点,向右上。。

按照这个规率找到各个状态机之间的切换原理,就可以解决这个题目,

状态机切换用 if (state)...else if (....).或者switch(state)....case.....

#include <vector>
#include <iostream>
#include <string>

#define M 4
#define N 6

enum EState
{
    RIGHT,
    RIGHTUP,
    LEFTDOWN,
    DOWN,
    NONE
};

std::string GetState(EState state) {
    switch (state)
    {
    case EState::RIGHT:
        return "right";
    case EState::RIGHTUP:
        return "rightup";
    case EState::LEFTDOWN:
        return "leftdown";
    case EState::DOWN:
        return "down";  
    default:
        break;
    }
    return "none";
}

int main(int argc, char const *argv[])
{
    std::vector<std::vector<int>> arr;
    int val = 0;
    for (int i = 0; i < M; i++) {
        std::vector<int> tmp;
        for (int j = 0; j < N; j++) {
            tmp.emplace_back(val++);
        }
        arr.emplace_back(tmp);
    }

    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            printf("%3d  ", arr[i][j]);
        }
        printf("\n");
    }


    printf("=====================\n");

    int row = 0, col = 0; // row, col
    EState nextState = EState::NONE;
    int idx = 0;
    int target[M][N];
    target[0][0] = arr[0][0];
    while (idx < M * N) {
        // target[row][col] = arr[row][col];
        // printf(">>>>>>%3d  %s\n", arr[row][col], GetState(nextState).c_str());
        printf("%3d  ", arr[row][col]);
        if (row == 0 && col == 0) {
            col++;
            nextState = EState::RIGHT;
            idx++;
            continue;
        }
        switch (nextState)
        {
        case EState::RIGHT:
            if (row == 0) { // left edge
                row++;
                col--;
                nextState = EState::LEFTDOWN;
            } else { // right up
                row--;
                col++;
                nextState = EState::RIGHTUP;
            }
            break;
        case EState::RIGHTUP:
            if (row == 0) {
                if (col == N - 1) {
                    row ++;
                    nextState = EState::DOWN;
                } else {
                    col++;
                    nextState = EState::RIGHT;
                }
            } else {
                if (col == N - 1) {
                    row ++;
                    nextState = EState::DOWN;
                } else {
                    row--;
                    col ++;
                    nextState = EState::RIGHTUP;
                }   
            }
            break;
        case EState::LEFTDOWN:
            if (col == 0) {
                if (row == M - 1) {
                    col++;
                    nextState = EState::RIGHT;
                } else {
                    row++;
                    nextState = EState::DOWN;
                }
            } else {
                if (row == M -1) {
                    col++;
                    nextState = EState::RIGHT;
                } else {
                    col--;
                    row++;
                    nextState = EState::LEFTDOWN;
                }
            }
            break;
        case EState::DOWN:
                if (row == M - 1) {
                    if (col == 0) {
                        row --;
                        col ++;
                        nextState = EState::RIGHTUP;
                    } else {
                        col ++;
                        nextState = EState::RIGHT;
                    }
                } else {
                    if (col == N - 1) {
                        row++;
                        col--;
                        nextState = EState::LEFTDOWN; 
                    } else {
                        row --;
                        col ++;
                        nextState = EState::RIGHTUP;
                    }
                }
            break;
        default:
            break;
        }
        idx++;
    }
    printf("\n");
    return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值