C 将矩阵2D变换为1D

C 将矩阵2D变换为1D,c,vector,matrix,C,Vector,Matrix,我有一个问题,将2D矩阵传递给带有C函数的向量(1D数组)。下面是我要创建的代码: #include <stdio.h> #define N 64 #define A 8 int tab2[A][A]; int vect[N]; void fonc(int i,int j,int k,int l,int c,int **tab2,int *vect); void fonc(int i,int j,int k,int l,int c,int **tab2,int *vect)

我有一个问题,将2D矩阵传递给带有C函数的向量(1D数组)。下面是我要创建的代码:

#include <stdio.h>
#define N  64
#define A  8


int tab2[A][A];
int vect[N];
void fonc(int i,int j,int k,int l,int c,int **tab2,int *vect);

void fonc(int i,int j,int k,int l,int c,int **tab2,int *vect){

vect[k]=tab2[0][0];
printf("%d",vect[k]);
  while(i!=8 && j!=8)
    {
        //bas
        i=i;
    j=j+1;


    vect[k]++;
      printf("%d\t",vect[k]);
    //descente
    while(j !=0)
    {
     i=i+1;
     j=j-1;

     vect[k]++;
    }

    //droite
    i=i;
    j=j+1;

    vect[k]++;
     //montée
    while(i !=0)
    {
     i=i-1;
     j=j+1;

     vect[k]++;
    }
    }

}



int main (){
    int vect[64] ;
int tab2[8][8]={
{1, 2, 6, 7, 15, 16 ,28 ,1},
{3, 5, 8, 14, 17 ,27 ,29 ,1},
{4, 9, 13, 18, 26, 30, 39 ,1},
{10, 12, 19, 25, 31 ,38 ,40 ,1},
{11, 20 ,24, 32 ,37 ,41 ,46 ,1} ,
{21 ,23, 33, 36, 42, 45, 47 ,1},
{22, 34 ,35, 43, 44, 48, 49 ,1},
{22, 34 ,35, 43, 44, 48, 49 ,1}};
    int i;
    int j;
    int k;

fonc(i,j,k,8,8,tab2,vect);
//printf("%d\n", ) ;//limpide !
return 0;
}

这就是你如何用17倍更少的行完成它:

#define N 8

int mat2d[N][N] = { /* stuff */ };
int vec1d[N * N];
memcpy(vec1d, mat2d, sizeof vec1d);

您的函数有3个不必要的参数-
i
j
k
。传递给函数的
main()
中的值未初始化;函数中传入的
i
j
值不相关,因为代码在首次使用时设置变量。使用
k
中的值,但传递给函数的值不确定。这需要更改,以便减少三个参数,它们只是函数中的局部变量,并且都需要设置为零。(
k
是向量中的索引,其中应分配矩阵中的下一个值;
i
j
是数组的下标)

你应该失去两个全局变量;它们从未被引用,因为
main()
中的局部变量隐藏了它们,函数的参数也隐藏了它们。两个
#define
值也从未使用过

虽然传递了
l
c
(行和列),但忽略它们并假定上界为
l=8
c=8
。此外,您尝试传递给
fonc
的类型不是
int**tab2
;它是
inttab2[][8]
inttab2[8][8]
。函数签名也可以是:

void fonc(int tab2[8][8], int *vect);
在函数中,形式为
vect[k]++的每个赋值
应该是形式为
vect[k++]=tab2[i][j]的赋值

锯齿形算法很容易编码。对于8x8固定大小的矩阵,只需将索引序列打包到一个数组中即可。我假设锯齿图的左上角是(0,0),右下角是(7,7)。如果这是错误的,您只需修复表的初始值设定项

static const struct ZigZag
{
    unsigned char y, x;  // Reversed from original
} zigzag[] =
{
    { 0, 0 }, { 1, 0 }, { 0, 1 }, { 0, 2 },
    { 1, 1 }, { 2, 0 }, { 3, 0 }, { 2, 1 },
    { 1, 2 }, { 0, 3 }, { 0, 4 }, { 1, 3 },
    ...
    { 7, 5 }, { 7, 6 }, { 6, 7 }, { 7, 7 },
};
正确的复制操作很简单:

for (int i = 0; i < 64; i++)
    vect[i] = tab[zigzag[i].x][zigzag[i].y];
然后使用更复杂的下标表达式:

vect[i] = tab[zigzag[i] >> 4][zigzag[i] & 0xF];
它可能会更快,因为内存访问更少-您必须进行测量

这一切都假设您正在处理8x8固定大小的方形阵列。如果你必须处理任意大小的数组,并且仍然要做这项工作,那么你可能必须编码一些东西,以便指定起点,向右走一步,沿对角线向左走直到到达边缘(左或下),向下走一步或向右走一步,沿对角线向右走直到到达边缘(上或右),你向右或向下走一步,然后重复,直到到达终点。那就是精巧地编写代码;复制循环不会有两行

从问题中插入指令的代码 下面是问题中的代码,虽然稍微清理了一下,但是
fonc()
中的核心算法没有改变-至少在处理
i
j
k
时没有改变,只是初始化了它们。main函数在调用
fonc()
之前和之后打印出矩阵和向量。
fonc()
中对向量的每个赋值都已修复并插入指令

#include <stdio.h>

void fonc(int tab2[8][8], int *vect);

void fonc(int tab2[8][8], int *vect)
{
    int i = 0;
    int j = 0;
    int k = 0;

    vect[k] = tab2[i][j];
    printf("v[%2d] = m[%2d][%2d] = %d\n", k, i, j, tab2[i][j]);

    while (i != 8 && j != 8)
    {
        // bas
        i = i;
        j = j+1;
        vect[k++] = tab2[i][j];
        printf("v[%2d] = m[%2d][%2d] = %d\n", k, i, j, tab2[i][j]);

        // descente
        while (j != 0)
        {
            i = i+1;
            j = j-1;
            vect[k++] = tab2[i][j];
            printf("v[%2d] = m[%2d][%2d] = %d\n", k, i, j, tab2[i][j]);
        }

        // droite
        i = i;
        j = j+1;
        vect[k++] = tab2[i][j];
        printf("v[%2d] = m[%2d][%2d] = %d\n", k, i, j, tab2[i][j]);

        // montée
        while (i != 0)
        {
            i = i-1;
            j = j+1;
            printf("v[%2d] = m[%2d][%2d] = %d\n", k, i, j, tab2[i][j]);
            vect[k++] = tab2[i][j];
        }
    }
}

int main(void)
{
    int vect[64];
    int tab2[8][8] =
    {
        // Up to element value 28, the data should appear in
        // the order 1, 2, 3, ... in the output vector
        {1, 2, 6, 7, 15, 16, 28, 1},
        {3, 5, 8, 14, 17, 27, 29, 1},
        {4, 9, 13, 18, 26, 30, 39, 1},
        {10, 12, 19, 25, 31, 38, 40, 1},
        {11, 20, 24, 32, 37, 41, 46, 1},
        {21, 23, 33, 36, 42, 45, 47, 1},
        {22, 34, 35, 43, 44, 48, 49, 1},
        {22, 34, 35, 43, 44, 48, 49, 1}
    };

    for (int i = 0; i < 8; i++)
    {
        for (int j = 0; j < 8; j++)
            printf("%3d", tab2[i][j]);
        putchar('\n');
    }

    fonc(tab2, vect);

    for (int i = 0; i < 8 * 8; i++)
    {
        printf("%3d", vect[i]);
        if (i % 8 == 7)
            putchar('\n');
    }

    return 0;
}
请注意:

  • 您可以访问
    tab2[0][8]
    ,这超出了范围
  • 当对角线运动到达矩阵的底部或右侧时,您的算法会遇到问题
  • 如果您没有C99和VLA支持,那么处理变量NxM阵列将是一件痛苦的事情
  • 表驱动程序 匿名检测的代码版本 提供了一个。这在概念上很有趣,但我不确定它是否准确。检测它以便它打印其输入和输出不是决定性的,因此我将其放入与上面代码相同的表中,该表应生成向量1..64。代码和输出为:

    #include <stdio.h>
    
    #define max(a, b) ((a) > (b) ? (a) : (b))
    #define min(a, b) ((a) > (b) ? (b) : (a))
    
    void dezigzag(int out[64], int in[8][8])
    {
        int n = 0;
        for (int diag = 0; diag < 15; diag++)
        {
            for (int i = max(0, diag - 7); i <= min(7, diag); i++)
                out[n++] = diag % 2 ? in[diag - i][i] : in[i][diag - i];
        }
    }
    
    int main(void)
    {
        int out[64] = {-1};
        int in[8][8];
    
        for (int i = 0; i < 64; i++)
            in[i % 8][i / 8] = i;
    
        puts("Matrix:");
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 8; j++)
                printf("%3d", in[i][j]);
            putchar('\n');
        }
    
        dezigzag(out, in);
    
        puts("Vector:");
        for (int i = 0; i < 8 * 8; i++)
        {
            printf("%3d", out[i]);
            if (i % 8 == 7)
                putchar('\n');
        }
    
        //for (int i = 0; i < 64; i++) {
        //    printf("%d: %d\n", i, out[i]);
        //}
    
        int tab2[8][8] =
        {
            {  1,  2,  6,  7, 15, 16, 28, 29 },
            {  3,  5,  8, 14, 17, 27, 30, 43 },
            {  4,  9, 13, 18, 26, 31, 42, 44 },
            { 10, 12, 19, 25, 32, 41, 45, 54 },
            { 11, 20, 24, 33, 40, 46, 53, 55 },
            { 21, 23, 34, 39, 47, 52, 56, 61 },
            { 22, 35, 38, 48, 51, 57, 60, 62 },
            { 36, 37, 49, 50, 58, 59, 63, 64 },
        };
    
        puts("Matrix:");
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 8; j++)
                printf("%3d", tab2[i][j]);
            putchar('\n');
        }
    
        dezigzag(out, tab2);
    
        puts("Vector:");
        for (int i = 0; i < 8 * 8; i++)
        {
            printf("%3d", out[i]);
            if (i % 8 == 7)
                putchar('\n');
        }
    
        return 0;
    }
    
    这个结果并不完全正确,但我相信这是正确的方向。(同样清楚的是,这太复杂了,无法对Anonymous的问题发表评论——因此这里添加了此项内容。)

    从概念上讲,代码是旋转方阵,使其站在其点上,然后在(8+8-1)行上水平来回扫描

    用于3x3扫描的ASCII艺术:

       /\
      /\/\
     /\/\/\
     \/\/\/
      \/\/
       \/
    
    有(3+3-1)=5个扫描行。在表驱动的代码中,与此对应的数据具有规律性

    修复匿名者的代码 在函数
    dezigzag()
    中,赋值行需要反转条件。现行守则相当于:

    out[n++] = (diag % 2 == 1) ? in[diag - i][i] : in[i][diag - i];
    
    正确的代码是:

    out[n++] = (diag % 2 == 0) ? in[diag - i][i] : in[i][diag - i];
    
    然后输出为:

    Matrix:
      0  8 16 24 32 40 48 56
      1  9 17 25 33 41 49 57
      2 10 18 26 34 42 50 58
      3 11 19 27 35 43 51 59
      4 12 20 28 36 44 52 60
      5 13 21 29 37 45 53 61
      6 14 22 30 38 46 54 62
      7 15 23 31 39 47 55 63
    Vector:
      0  8  1  2  9 16 24 17
     10  3  4 11 18 25 32 40
     33 26 19 12  5  6 13 20
     27 34 41 48 56 49 42 35
     28 21 14  7 15 22 29 36
     43 50 57 58 51 44 37 30
     23 31 38 45 52 59 60 53
     46 39 47 54 61 62 55 63
    Matrix:
      1  2  6  7 15 16 28 29
      3  5  8 14 17 27 30 43
      4  9 13 18 26 31 42 44
     10 12 19 25 32 41 45 54
     11 20 24 33 40 46 53 55
     21 23 34 39 47 52 56 61
     22 35 38 48 51 57 60 62
     36 37 49 50 58 59 63 64
    Vector:
      1  2  3  4  5  6  7  8
      9 10 11 12 13 14 15 16
     17 18 19 20 21 22 23 24
     25 26 27 28 29 30 31 32
     33 34 35 36 37 38 39 40
     41 42 43 44 45 46 47 48
     49 50 51 52 53 54 55 56
     57 58 59 60 61 62 63 64
    

    处理MxN阵列的代码
    #包括
    静态内联intmax(inta,intb){返回(a>b)?a:b;}
    静态内联intmin(inta,intb){返回(a对于(int j=min_x;j在正方形的对角线上迭代,每次交替方向

    下面是一个完整的工作示例(在c99中)

    #包括
    #定义最大值(a,b)((a)>(b)?(a):(b))
    #定义最小值(a,b)((a)>(b)?(b):(a))
    void dezigzag(int-out[64],int-in[8][8]){
    int n=0;
    用于(int diag=0;diag<15;diag++){
    
    对于(int i=max(0,diag-7);i所有不需要传递到函数的
    i
    j
    k
    值都是不确定的,因此这是未定义的行为
    #include <stdio.h>
    
    #define max(a, b) ((a) > (b) ? (a) : (b))
    #define min(a, b) ((a) > (b) ? (b) : (a))
    
    void dezigzag(int out[64], int in[8][8])
    {
        int n = 0;
        for (int diag = 0; diag < 15; diag++)
        {
            for (int i = max(0, diag - 7); i <= min(7, diag); i++)
                out[n++] = diag % 2 ? in[diag - i][i] : in[i][diag - i];
        }
    }
    
    int main(void)
    {
        int out[64] = {-1};
        int in[8][8];
    
        for (int i = 0; i < 64; i++)
            in[i % 8][i / 8] = i;
    
        puts("Matrix:");
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 8; j++)
                printf("%3d", in[i][j]);
            putchar('\n');
        }
    
        dezigzag(out, in);
    
        puts("Vector:");
        for (int i = 0; i < 8 * 8; i++)
        {
            printf("%3d", out[i]);
            if (i % 8 == 7)
                putchar('\n');
        }
    
        //for (int i = 0; i < 64; i++) {
        //    printf("%d: %d\n", i, out[i]);
        //}
    
        int tab2[8][8] =
        {
            {  1,  2,  6,  7, 15, 16, 28, 29 },
            {  3,  5,  8, 14, 17, 27, 30, 43 },
            {  4,  9, 13, 18, 26, 31, 42, 44 },
            { 10, 12, 19, 25, 32, 41, 45, 54 },
            { 11, 20, 24, 33, 40, 46, 53, 55 },
            { 21, 23, 34, 39, 47, 52, 56, 61 },
            { 22, 35, 38, 48, 51, 57, 60, 62 },
            { 36, 37, 49, 50, 58, 59, 63, 64 },
        };
    
        puts("Matrix:");
        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 8; j++)
                printf("%3d", tab2[i][j]);
            putchar('\n');
        }
    
        dezigzag(out, tab2);
    
        puts("Vector:");
        for (int i = 0; i < 8 * 8; i++)
        {
            printf("%3d", out[i]);
            if (i % 8 == 7)
                putchar('\n');
        }
    
        return 0;
    }
    
    Matrix:
      0  8 16 24 32 40 48 56
      1  9 17 25 33 41 49 57
      2 10 18 26 34 42 50 58
      3 11 19 27 35 43 51 59
      4 12 20 28 36 44 52 60
      5 13 21 29 37 45 53 61
      6 14 22 30 38 46 54 62
      7 15 23 31 39 47 55 63
    Vector:
      0  1  8 16  9  2  3 10
     17 24 32 25 18 11  4  5
     12 19 26 33 40 48 41 34
     27 20 13  6  7 14 21 28
     35 42 49 56 57 50 43 36
     29 22 15 23 30 37 44 51
     58 59 52 45 38 31 39 46
     53 60 61 54 47 55 62 63
    Matrix:
      1  2  6  7 15 16 28 29
      3  5  8 14 17 27 30 43
      4  9 13 18 26 31 42 44
     10 12 19 25 32 41 45 54
     11 20 24 33 40 46 53 55
     21 23 34 39 47 52 56 61
     22 35 38 48 51 57 60 62
     36 37 49 50 58 59 63 64
    Vector:
      1  3  2  6  5  4 10  9
      8  7 15 14 13 12 11 21
     20 19 18 17 16 28 27 26
     25 24 23 22 36 35 34 33
     32 31 30 29 43 42 41 40
     39 38 37 49 48 47 46 45
     44 54 53 52 51 50 58 57
     56 55 61 60 59 63 62 64
    
       /\
      /\/\
     /\/\/\
     \/\/\/
      \/\/
       \/
    
    out[n++] = (diag % 2 == 1) ? in[diag - i][i] : in[i][diag - i];
    
    out[n++] = (diag % 2 == 0) ? in[diag - i][i] : in[i][diag - i];
    
    Matrix:
      0  8 16 24 32 40 48 56
      1  9 17 25 33 41 49 57
      2 10 18 26 34 42 50 58
      3 11 19 27 35 43 51 59
      4 12 20 28 36 44 52 60
      5 13 21 29 37 45 53 61
      6 14 22 30 38 46 54 62
      7 15 23 31 39 47 55 63
    Vector:
      0  8  1  2  9 16 24 17
     10  3  4 11 18 25 32 40
     33 26 19 12  5  6 13 20
     27 34 41 48 56 49 42 35
     28 21 14  7 15 22 29 36
     43 50 57 58 51 44 37 30
     23 31 38 45 52 59 60 53
     46 39 47 54 61 62 55 63
    Matrix:
      1  2  6  7 15 16 28 29
      3  5  8 14 17 27 30 43
      4  9 13 18 26 31 42 44
     10 12 19 25 32 41 45 54
     11 20 24 33 40 46 53 55
     21 23 34 39 47 52 56 61
     22 35 38 48 51 57 60 62
     36 37 49 50 58 59 63 64
    Vector:
      1  2  3  4  5  6  7  8
      9 10 11 12 13 14 15 16
     17 18 19 20 21 22 23 24
     25 26 27 28 29 30 31 32
     33 34 35 36 37 38 39 40
     41 42 43 44 45 46 47 48
     49 50 51 52 53 54 55 56
     57 58 59 60 61 62 63 64
    
    #include <stdio.h>
    
    static inline int max(int a, int b) { return (a > b) ? a : b; }
    static inline int min(int a, int b) { return (a < b) ? a : b; }
    
    static void print_info(int rows, int cols)
    {
        int n = rows + cols - 1;
        printf("R = %d, C = %d, N = %d\n", rows, cols, n);
        for (int i = 0; i < n; i++)
        {
            int max_x = min(i, cols-1);
            int min_x = max(0, i - n + cols);
            int max_y = min(i, rows-1);
            int min_y = max(0, i - n + rows);
            printf("i = %d, min_x = %d, max_x = %d, min_y = %d, max_y = %d\n",
                    i, min_x, max_x, min_y, max_y);
        }
    
        for (int i = 0; i < n; i++)
        {
            printf("%2d:", i);
            if (i % 2 == 0)
            {
                int max_x = min(i, cols-1);
                int min_x = max(0, i - n + cols);
                for (int j = min_x; j <= max_x; j++)
                    /* (row,col) */
                    printf(" (r=%d,c=%d)", i - j, j);
            }
            else
            {
                int max_y = min(i, rows-1);
                int min_y = max(0, i - n + rows);
                for (int j = min_y; j <= max_y; j++)
                    printf(" (r=%d,c=%d)", j, i - j);
            }
            putchar('\n');
        }
    }
    
    static void set_zigzag(int rows, int cols, int matrix[rows][cols])
    {
        int x = 0;
        int n = rows + cols - 1;
        for (int i = 0; i < n; i++)
        {
            if (i % 2 == 0)
            {
                int max_x = min(i, cols-1);
                int min_x = max(0, i - n + cols);
                for (int j = min_x; j <= max_x; j++)
                    matrix[i-j][j] = x++;
            }
            else
            {
                int max_y = min(i, rows-1);
                int min_y = max(0, i - n + rows);
                for (int j = min_y; j <= max_y; j++)
                    matrix[j][i-j] = x++;
            }
        }
    }
    
    static void zigzag(int rows, int cols, int matrix[rows][cols], int vector[rows*cols])
    {
        int n = rows + cols - 1;
        int v = 0;
        for (int i = 0; i < n; i++)
        {
            if (i % 2 == 0)
            {
                int max_x = min(i, cols-1);
                int min_x = max(0, i - n + cols);
                for (int j = min_x; j <= max_x; j++)
                    vector[v++] = matrix[i-j][j];
            }
            else
            {
                int max_y = min(i, rows-1);
                int min_y = max(0, i - n + rows);
                for (int j = min_y; j <= max_y; j++)
                    vector[v++] = matrix[j][i-j];
            }
        }
    }
    
    static void dump_matrix(const char *tag, int rows, int cols, int matrix[rows][cols])
    {
        printf("%s (%d x %d):\n", tag, rows, cols);
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
                printf("%3d", matrix[i][j]);
            putchar('\n');
        }
    }
    
    static void dump_vector(const char *tag, int rows, int cols, int vector[rows * cols])
    {
        printf("%s (%d : %d):\n", tag, rows, cols);
        for (int i = 0; i < rows * cols; i++)
        {
            printf("%3d", vector[i]);
            if (i % cols == cols - 1)
                putchar('\n');
        }
    }
    
    static void test_rows_x_cols(int rows, int cols)
    {
        int vector[rows * cols];
        int matrix[rows][cols];
    
        printf("\nTest %dx%d\n\n", rows, cols);
        print_info(rows, cols);
        set_zigzag(rows, cols, matrix);
        dump_matrix("Matrix", rows, cols, matrix);
        zigzag(rows, cols, matrix, vector);
        dump_vector("Vector", rows, cols, vector);
    }
    
    int main(void)
    {
        struct
        {
            int rows;
            int cols;
        } test[] =
        {
            { 4, 4 }, { 6, 4 }, { 4, 7 }, { 7, 14 }, { 6, 16 }, { 3, 33 },
        };
        enum { NUM_TEST = sizeof(test) / sizeof(test[0]) };
    
        for (int i = 0; i < NUM_TEST; i++)
            test_rows_x_cols(test[i].rows, test[i].cols);
    
        return 0;
    }
    
    #include <assert.h>
    #include <limits.h>
    #include <stdbool.h>
    #include <stdio.h>
    
    typedef struct RC
    {
        int row;
        int col;
    } RC;
    
    typedef struct RLE
    {
        RC  curr;
        RC  size;
        int zigzag;
        int sequence;
    } RLE;
    
    static inline int max(int a, int b) { return (a > b) ? a : b; }
    static inline int min(int a, int b) { return (a < b) ? a : b; }
    
    static inline int get_num_zigzags(const RLE *rle)
    {
        return rle->size.row + rle->size.col - 1;
    }
    
    static inline int get_max_row(const RLE *rle)
    {
        return min(rle->zigzag, rle->size.row - 1);
    }
    
    static inline int get_min_row(const RLE *rle)
    {
        return max(0, rle->zigzag - get_num_zigzags(rle) + rle->size.row);
    }
    
    static inline int get_max_col(const RLE *rle)
    {
        return min(rle->zigzag, rle->size.col - 1);
    }
    
    static inline int get_min_col(const RLE *rle)
    {
        return max(0, rle->zigzag - get_num_zigzags(rle) + rle->size.col);
    }
    
    static inline int get_row_from_col(const RLE *rle)
    {
        return rle->zigzag - rle->curr.col;
    }
    
    static inline int get_col_from_row(const RLE *rle)
    {
        return rle->zigzag - rle->curr.row;
    }
    
    static RLE RLE_init(int rows, int cols)
    {
        RLE rle;
        assert(rows > 0 && cols > 0);
        assert(INT_MAX / rows >= cols);
        rle.curr.row = 0;
        rle.curr.col = 0;
        rle.size.row = rows;
        rle.size.col = cols;
        rle.zigzag = 0;
        rle.sequence = 0;
        return(rle);
    }
    
    static inline RC RLE_position(const RLE *rle)
    {
        return rle->curr;
    }
    
    static inline int RLE_row(const RLE *rle)
    {
        return rle->curr.row;
    }
    
    static inline int RLE_col(const RLE *rle)
    {
        return rle->curr.col;
    }
    
    static inline int RLE_sequence(const RLE *rle)
    {
        return rle->sequence;
    }
    
    static inline int RLE_zigzag(const RLE *rle)
    {
        return rle->zigzag;
    }
    
    static inline RC RLE_size(const RLE *rle)
    {
        return rle->size;
    }
    
    static inline bool RLE_finished(const RLE *rle)
    {
        return(rle->sequence == rle->size.row * rle->size.col);
    }
    
    static void RLE_check(const RLE *rle)
    {
        assert(rle->size.row > 0);
        assert(rle->size.col > 0);
        assert(rle->curr.row < rle->size.row && rle->curr.row >= 0);
        assert(rle->curr.col < rle->size.col && rle->curr.col >= 0);
        assert(rle->zigzag >= 0 && rle->zigzag < rle->size.row + rle->size.col - 1);
        assert(rle->sequence >= 0 && rle->sequence <= rle->size.row * rle->size.col);
    }
    
    #if defined(REL_DUMP_REQUIRED)
    static void RLE_dump(const char *tag, const RLE *rle)
    {
        printf("Dump RLE (%s):", tag);
        RC size = RLE_size(rle);
        assert(size.row == rle->size.row);
        assert(size.col == rle->size.col);
        printf("    Rows = %2d, Cols = %2d, Zigzags = %2d; ",
               rle->size.row, rle->size.col, rle->size.row + rle->size.col - 1);
        RC posn = RLE_position(rle);
        assert(posn.row == rle->curr.row);
        assert(posn.col == rle->curr.col);
        assert(posn.row == RLE_row(rle));
        assert(posn.col == RLE_col(rle));
        printf(" Position: r = %d, c = %d; ", RLE_row(rle), RLE_col(rle));
        assert(RLE_zigzag(rle) == rle->zigzag);
        assert(RLE_sequence(rle) == rle->sequence);
        printf(" Zigzag = %d, Sequence = %d\n", rle->zigzag, rle->sequence);
        RLE_check(rle);
    }
    #endif
    
    static void RLE_next(RLE *rle)
    {
        RLE_check(rle);
    
        /* Already finished? */
        if (RLE_finished(rle))
            return;
        rle->sequence++;
        /* Finished now? */
        if (RLE_finished(rle))
            return;
    
        if (rle->zigzag % 2 == 0)
        {
            if (rle->curr.col < get_max_col(rle))
            {
                /* Same zigzag */
                rle->curr.col++;
                rle->curr.row = get_row_from_col(rle);
            }
            else
            {
                /* Next zigzag */
                rle->zigzag++;
                rle->curr.row = get_min_row(rle);
                rle->curr.col = get_col_from_row(rle);
            }
        }
        else
        {
            if (rle->curr.row < get_max_row(rle))
            {
                /* Same zigzag */
                rle->curr.row++;
                rle->curr.col = get_col_from_row(rle);
            }
            else
            {
                /* Next zigzag */
                rle->zigzag++;
                rle->curr.col = get_min_col(rle);
                rle->curr.row = get_row_from_col(rle);
            }
        }
    }
    
    static void print_info(int rows, int cols)
    {
        int n = rows + cols - 1;
        printf("R = %d, C = %d, N = %d\n", rows, cols, n);
    
        for (int zigzag = 0; zigzag < n; zigzag++)
        {
            int max_col = min(zigzag, cols-1);
            int min_col = max(0, zigzag - n + cols);
            int max_row = min(zigzag, rows-1);
            int min_row = max(0, zigzag - n + rows);
            printf("zigzag = %2d, min_col = %2d, max_col = %2d, min_row = %2d, max_row = %2d\n",
                    zigzag, min_col, max_col, min_row, max_row);
        }
    
        for (int zigzag = 0; zigzag < n; zigzag++)
        {
            printf("%d:", zigzag);
            if (zigzag % 2 == 0)
            {
                int max_col = min(zigzag, cols-1);
                int min_col = max(0, zigzag - n + cols);
                for (int col = min_col; col <= max_col; col++)
                    /* (row,col) */
                    printf(" (r=%d,c=%d)", zigzag - col, col);
            }
            else
            {
                int max_row = min(zigzag, rows-1);
                int min_row = max(0, zigzag - n + rows);
                for (int row = min_row; row <= max_row; row++)
                    printf(" (r=%d,c=%d)", row, zigzag - row);
            }
            putchar('\n');
        }
    }
    
    static void dump_matrix(const char *tag, int rows, int cols, int matrix[rows][cols])
    {
        printf("%s (%d x %d):\n", tag, rows, cols);
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
                printf("%3d", matrix[i][j]);
            putchar('\n');
        }
    }
    
    static void dump_vector(const char *tag, int rows, int cols, int vector[rows * cols])
    {
        printf("%s (%d : %d):\n", tag, rows, cols);
        for (int i = 0; i < rows * cols; i++)
        {
            printf("%3d", vector[i]);
            if (i % cols == cols - 1)
                putchar('\n');
        }
    }
    
    static void RLE_demonstration(int rows, int cols)
    {
        int matrix[rows][cols];
        int vector[rows*cols];
    
        /* Set matrix */
        for (RLE rle = RLE_init(rows, cols); !RLE_finished(&rle); RLE_next(&rle))
        {
            //RLE_dump("Set Matrix", &rle);
            RC rc = RLE_position(&rle); 
            matrix[rc.row][rc.col] = RLE_sequence(&rle);
        }
        dump_matrix("Matrix", rows, cols, matrix);
    
        /* Convert matrix to vector */
        for (RLE rle = RLE_init(rows, cols); !RLE_finished(&rle); RLE_next(&rle))
        {
            //RLE_dump("Get Matrix", &rle);
            RC rc = RLE_position(&rle); 
            vector[RLE_sequence(&rle)] = matrix[rc.row][rc.col];
        }
        dump_vector("Vector", rows, cols, vector);
    }
    
    int main(int argc, char **argv)
    {
        struct
        {
            int rows;
            int cols;
        } test[] =
        {
            { 4, 4 }, { 6, 4 },  { 4, 7 }, { 7, 14 }, { 6, 16 }, { 3, 33 },
        };
        enum { NUM_TEST = sizeof(test) / sizeof(test[0]) };
    
        /* argv != 0 avoids unused variable warning */
        int verbose = (argv != 0 && argc > 1) ? 1 : 0;
    
        for (int i = 0; i < NUM_TEST; i++)
        {
            if (verbose)
                print_info(test[i].rows, test[i].cols);
            RLE_demonstration(test[i].rows, test[i].cols);
        }
    
        return 0;
    }
    
    #include <stdio.h>
    
    #define max(a, b) ((a) > (b) ? (a) : (b))
    #define min(a, b) ((a) > (b) ? (b) : (a))
    
    void dezigzag(int out[64], int in[8][8]) {
        int n = 0;
        for (int diag = 0; diag < 15; diag++) {
            for (int i = max(0, diag - 7); i <= min(7, diag); i++) {
                out[n++] = diag % 2 ? in[diag - i][i] : in[i][diag - i];
            }
        }
    }
    
    int main(int argc, char *argv[]) {
        int out[64] = {-1};
        int in[8][8];
        for (int i = 0; i < 64; i++) {
            in[i % 8][i / 8] = i;
        }
        dezigzag(out, in);
        for (int i = 0; i < 64; i++) {
            printf("%d: %d\n", i, out[i]);
        }
        return 0;
    }