C 将矩阵2D变换为1D
我有一个问题,将2D矩阵传递给带有C函数的向量(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)
#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;
}