ANSI C 中的锯齿形数组

Posted

技术标签:

【中文标题】ANSI C 中的锯齿形数组【英文标题】:Zigzag array in ANSI C 【发布时间】:2016-11-30 06:51:39 【问题描述】:

我只是一个初学者,我正在尝试弄清楚如何创建二维数组,其中填充有对角线的数字,如 JPEG 之字形排序:https://en.wikipedia.org/wiki/File:JPEG_ZigZag.svg

我想出了如何获取左上部分:

r=1;
for(z=0;z<n;z++)

    if(z%2=0)
    
        for(i=0;i<=z;i++)
        
           t[z-i][i]=r;
           ++r;
        
    
    else
    
        for(i=0;i<=z;i++)
        
           t[i][z-i]=r;
           ++r;
        
    
  

它工作正常,但我不知道如何得到它的其余部分。

【问题讨论】:

看看"Rosetta code - Zig-zag matrix"。 话虽如此,您可以再创建 2 个循环,一个封装您的迭代,另一个循环抵消您的循环,两个循环都必须嵌套在条件语句和父循环的计数中将选择条件语句以遍历正确的方式。虽然,在我的脑海中,我提出的解决方案增加了算法的复杂性。请记住,我从星期一早上起就没有睡觉,昨晚我住在快捷假日酒店。 @J. Piquard 我看到了,但是那里显示的 C 代码对我来说太高级了。 我看到移动模式的方式是这样的: 1. 从 [0,0] 开始。 2. 水平前进一步到 [1,0]。 3. 沿对角线、水平向后和垂直向前移动,直到碰到边缘(在本例中为 [0, 1])。 4. 垂直向前走一步到[0,2]。 5. 沿对角线、水平向前和垂直向后移动,直到碰到边缘(在本例中为 [2,0])。重复这个过程,直到在 [n,n] 处找到最后一个元素。 此页面简要介绍了 zig-zag 排序,并且作为奖励甚至包含一些代码。缺点是它执行莫顿顺序之字形,这与您提出的方案有些不同。这家伙现在与 NVIDIA afaik 合作,并且知道他的东西。 iquilezles.org/www/articles/wavelet/wavelet.htm 【参考方案1】:

我看到了,但是那里显示的 C 代码对我来说太高级了

您可以继续使用另一组嵌套的 for 循环和修改后的索引来做您正在做的事情:

#include <stdio.h>

void zigZagArray(int *array, int n) 
    int r = 1;

    for (int z = 0; z < n; z++) 
        if (z % 2 == 0) 
            for (int i = 0; i <= z; i++) 
                // array[z - i][i] = r++;
                *((array + (z - i) * n) + i) = r++;
            
         else 
            for (int i = 0; i <= z; i++) 
                // array[i][z - i] = r++;
                *((array + i * n) + z - i) = r++;
            
        
    

    for (int z = 1; z < n; z++) 
        if (z % 2 == n % 2) 
            for (int i = 1; i <= n - z; i++) 
                // array[z + i - 1][n - i] = r++;
                *((array + (z + i - 1) * n) + n - i) = r++;
            
         else 
            for (int i = 1; i <= n - z; i++) 
                // array[n - i][z + i - 1] = r++;
                *((array + (n - i) * n) + z + i - 1) = r++;
            
        
    


void printArray(int *array, int n)

    for (int i = 0; i < n; i++) 
        for (int j = 0; j < n; j++) 
            printf("%2d ", *((array + i * n) + j));
        
        printf("\n");
    


int main() 

    int a[7][7];
    zigZagArray((int *) a, 7);
    printArray((int *) a, 7);

    printf("\n");

    int b[8][8];
    zigZagArray((int *) b, 8);
    printArray((int *) b, 8);

    printf("\n");

    int c[9][9];
    zigZagArray((int *) c, 9);
    printArray((int *) c, 9);

    return 0;

输出

% ./a.out
 1  2  6  7 15 16 28 
 3  5  8 14 17 27 29 
 4  9 13 18 26 30 39 
10 12 19 25 31 38 40 
11 20 24 32 37 41 46 
21 23 33 36 42 45 47 
22 34 35 43 44 48 49 

 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 

 1  2  6  7 15 16 28 29 45 
 3  5  8 14 17 27 30 44 46 
 4  9 13 18 26 31 43 47 60 
10 12 19 25 32 42 48 59 61 
11 20 24 33 41 49 58 62 71 
21 23 34 40 50 57 63 70 72 
22 35 39 51 56 64 69 73 78 
36 38 52 55 65 68 74 77 79 
37 53 54 66 67 75 76 80 81 
%

【讨论】:

我明白了,如果给定大小是奇数还是偶数,结果会有所不同。这应该不是什么大问题。谢谢你:) @Piotr,修复结果很简单:将我的新代码中的 if (z % 2) 更改为 if (z % 2 == n % 2) 。我更新了我的代码并提供了示例输出以确认修复。享受吧。

以上是关于ANSI C 中的锯齿形数组的主要内容,如果未能解决你的问题,请参考以下文章

图像压缩 - 离散余弦变换后的锯齿形

LeetCode:Zigzag Convertsion(锯齿形转换-C语言版)

LeetCode:Zigzag Convertsion(锯齿形转换-C语言版)

字符串中最长的锯齿形子序列

为啥是锯齿形图形?

C# 中锯齿状数组的内存分配与 C++ 中的二维数组内存分配