你的函数有3个不必要的参数 —
i
,
j
和
k
。传递给函数的值在
main()
中未初始化;函数中传递的
i
和
j
的值是不相关的,因为代码在第一次使用变量时会设置它们的值。
k
的值被使用,但传递给函数的值是不确定的。需要更改这些参数,使它们成为函数内部的局部变量,并将其全部设置为零。(
k
是向量中下一个矩阵值应该分配的索引;
i
和
j
是数组的下标)。
你应该去掉这两个全局变量;它们从未被引用,因为在
main()
中的局部变量隐藏了它们,并且函数的参数也隐藏了它们。两个
#define
值也从未被使用。
虽然你传递了
l
和
c
(行和列),但你忽略了它们,并假设上限为
l = 8
和
c = 8
。另外,你尝试传递给
fonc
的类型不是
int **tab2
,而是
int tab2[][8]
或
int tab2[8][8]
。函数签名可以改为:
void fonc(int tab2[8][8], int *vect);
在你的函数中,每个形式为vect[k]++;
的赋值语句都应该改为形式为vect[k++] = tab2[i][j];
的赋值语句。
实现zig-zag算法很棘手。对于8x8固定大小的矩阵,把索引序列打包进数组是很诱人的。假设zig-zag图形的左上角为(0, 0),右下角为(7, 7)。如果这不对,你只需要修正表格的初始化即可。
static const struct ZigZag
{
unsigned char y, x;
} 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
vect[i] = tab[zigzag[i].x][zigzag[i].y]
我们可以讨论写64与sizeof(zigzag)/sizeof(zigzag[0])
的区别。如果你真的很缺内存(目前数据仅为128字节,所以我不相信你),那么你可以将两个坐标压缩成一个字节进行存储:
static const unsigned char zigzag[] =
{
0x00, 0x10, 0x01, 0x02, ...
};
然后使用更复杂的下标表达式:
vect[i] = tab[zigzag[i] >> 4][zigzag[i] & 0xF]
可能由于内存访问较少而更快 - 需要进行测量。
这一切都假设您正在处理8x8固定大小的正方形数组。 如果您必须处理任何大小的数组并仍要完成工作,则可能必须对事物进行编码,以便指定起始点,向右移动一步,对角线向左下移动,直到达到边缘(左侧或底部),向下或向右移动一步,对角线向右上移动,直到达到边缘(顶部或右侧),向右或向下移动一步,重复直到达到末尾。 编写代码将会比较繁琐;复制循环将不止两行。
来自问题的仪器化代码
这是问题中的代码,有所清理,但 fonc()
中的核心算法未更改 - 至少在处理 i
、j
和 k
时未更改,除了初始化它们。 主函数在调用 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)
{
i = i;
j = j+1;
vect[k++] = tab2[i][j];
printf("v[%2d] = m[%2d][%2d] = %d\n", k, i, j, tab2[i][j]);
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]);
}
i = i;
j = j+1;
vect[k++] = tab2[i][j];
printf("v[%2d] = m[%2d][%2d] = %d\n", k, i, j, tab2[i][j]);
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] =
{
{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;
}
示例输出:
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
v[ 0] = m[ 0][ 0] = 1
v[ 1] = m[ 0][ 1] = 2
v[ 2] = m[ 1][ 0] = 3
v[ 3] = m[ 1][ 1] = 5
v[ 3] = m[ 0][ 2] = 6
v[ 5] = m[ 0][ 3] = 7
v[ 6] = m[ 1][ 2] = 8
v[ 7] = m[ 2][ 1] = 9
v[ 8] = m[ 3][ 0] = 10
v[ 9] = m[ 3][ 1] = 12
v[ 9] = m[ 2][ 2] = 13
v[10] = m[ 1][ 3] = 14
v[11] = m[ 0][ 4] = 15
v[13] = m[ 0][ 5] = 16
v[14] = m[ 1][ 4] = 17
v[15] = m[ 2][ 3] = 18
v[16] = m[ 3][ 2] = 19
v[17] = m[ 4][ 1] = 20
v[18] = m[ 5][ 0] = 21
v[19] = m[ 5][ 1] = 23
v[19] = m[ 4][ 2] = 24
v[20] = m[ 3][ 3] = 25
v[21] = m[ 2][ 4] = 26
v[22] = m[ 1][ 5] = 27
v[23] = m[ 0][ 6] = 28
v[25] = m[ 0][ 7] = 1
v[26] = m[ 1][ 6] = 29
v[27] = m[ 2][ 5] = 30
v[28] = m[ 3][ 4] = 31
v[29] = m[ 4][ 3] = 32
v[30] = m[ 5][ 2] = 33
v[31] = m[ 6][ 1] = 34
v[32] = m[ 7][ 0] = 22
v[33] = m[ 7][ 1] = 34
v[33] = m[ 6][ 2] = 35
v[34] = m[ 5][ 3] = 36
v[35] = m[ 4][ 4] = 37
v[36] = m[ 3][ 5] = 38
v[37] = m[ 2][ 6] = 39
v[38] = m[ 1][ 7] = 1
v[39] = m[ 0][ 8] = 3
2 3 5 6 7 8 9 10
12 13 14 15 16 17 18 19
20 21 23 24 25 26 27 28
1 29 30 31 32 33 34 22
34 35 36 37 38 39 1 3
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
注意:
- 您访问了越界的
tab2[0][8]
。
- 当您的对角线运动撞到矩阵底部或右侧时,您的算法会遇到问题。
- 如果没有C99和VLA支持,处理可变的NxM数组将是一件麻烦的事情。
表驱动程序
#include <stdio.h>
void fonc(int tab2[8][8], int vect[8]);
void fonc(int tab2[8][8], int vect[8])
{
static const struct ZigZag
{
unsigned char y, x;
} zigzag[8*8] =
{
{ 0, 0 }, { 1, 0 }, { 0, 1 }, { 0, 2 },
{ 1, 1 }, { 2, 0 }, { 3, 0 }, { 2, 1 },
{ 1, 2 }, { 0, 3 }, { 0, 4 }, { 1, 3 },
{ 2, 2 }, { 3, 1 }, { 4, 0 }, { 5, 0 },
{ 4, 1 }, { 3, 2 }, { 2, 3 }, { 1, 4 },
{ 0, 5 }, { 0, 6 }, { 1, 5 }, { 2, 4 },
{ 3, 3 }, { 4, 2 }, { 5, 1 }, { 6, 0 },
{ 7, 0 }, { 6, 1 }, { 5, 2 }, { 4, 3 },
{ 3, 4 }, { 2, 5 }, { 1, 6 }, { 0, 7 },
{ 1, 7 }, { 2, 6 }, { 3, 5 }, { 4, 4 },
{ 5, 3 }, { 6, 2 }, { 7, 1 }, { 7, 2 },
{ 6, 3 }, { 5, 4 }, { 4, 5 }, { 3, 6 },
{ 2, 7 }, { 3, 7 }, { 4, 6 }, { 5, 5 },
{ 6, 4 }, { 7, 3 }, { 7, 4 }, { 6, 5 },
{ 5, 6 }, { 4, 7 }, { 5, 7 }, { 6, 6 },
{ 7, 5 }, { 7, 6 }, { 6, 7 }, { 7, 7 },
};
for (int i = 0; i < 64; i++)
vect[i] = tab2[zigzag[i].x][zigzag[i].y];
}
int main(void)
{
int vect[64];
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');
}
fonc(tab2, vect);
puts("Vector:");
for (int i = 0; i < 8 * 8; i++)
{
printf("%3d", vect[i]);
if (i % 8 == 7)
putchar('\n');
}
return 0;
}
示例输出:
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
Anonymous编写的代码的检测版
Anonymous提供了一个答案。它在概念上非常有趣,但我不确定它是否准确。为了检测它,使其打印出输入和输出是不够充分的,因此我加入了与上面代码相同的表格,应该产生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');
}
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
这个结果不完全正确,但我相信它是正确的方向。(同样明显的是,这个问题太复杂了,无法在对匿名用户的评论中进行解释-因此在这里进行补充。)
从概念上讲,代码将正方形矩阵旋转,使其立在其点上,然后水平来回扫描(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数组的代码
#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++)
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);
if (RLE_finished(rle))
return;
rle->sequence++;
if (RLE_finished(rle))
return;
if (rle->zigzag % 2 == 0)
{
if (rle->curr.col < get_max_col(rle))
{
rle->curr.col++;
rle->curr.row = get_row_from_col(rle);
}
else
{
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))
{
rle->curr.row++;
rle->curr.col = get_col_from_row(rle);
}
else
{
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++)
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];
for (RLE rle = RLE_init(rows, cols); !RLE_finished(&rle); RLE_next(&rle))
{
RC rc = RLE_position(&rle);
matrix[rc.row][rc.col] = RLE_sequence(&rle);
}
dump_matrix("Matrix", rows, cols, matrix);
for (RLE rle = RLE_init(rows, cols); !RLE_finished(&rle); RLE_next(&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]) };
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;
}
i
,j
和k
值是毫无意义的,因此这是未定义行为。它们不应该成为参数,而应该是函数内的本地变量,在任务执行前得到恰当的初始化。 - WhozCraig