C++问题---Zigzag数组输出

-------------------------------------
典型例题 29:C++问题---Zigzag数组输出
-------------------------------------
 1    /**
 2     * 得到如下样式的二维数组
 3     * zigzag(jpeg编码里取象素数据的排列顺序)
 4     *
 5     *   0, 1, 5, 6,14,15,27,28,
 6     *   2, 4, 7,13,16,26,29,42,
 7     *   3, 8,12,17,25,30,41,43,
 8     *   9,11,18,24,31,40,44,53,
 9     *   10,19,23,32,39,45,52,54,
10     *   20,22,33,38,46,51,55,60,
11     *   21,34,37,47,50,56,59,61,
12     *   35,36,48,49,57,58,62,63
13     */
14    #include <iostream>
15    #include <cstdio>
16    #include <cstdlib>
17   
18    using namespace std;
19   
20    int zigzag1(int N)
21    {
22        int s, i, j;
23        int squa;
24        /* 分配空间 */
25        int **a = (int **)malloc(N * sizeof(int *));
26        if(a == NULL)
27            return 0;
28        for(i = 0; i < N; i++) {
29            if((a[i] = (int*)malloc(N * sizeof(int))) == NULL) {
30                while(--i>=0)
31                    free(a[i]);
32                free(a);
33                return 0;
34            }
35        }
36        /* 数组赋值 */
37        squa = N*N;   
38        for(i = 0; i < N; i++)
39            for(j = 0; j < N; j++) {
40                s = i + j;
41                if(s < N)
42                    a[i][j] = s*(s+1)/2 + (((i+j)%2 == 0)? j : i);
43                else {
44                    s = (N-1-i) + (N-1-j);
45                    a[i][j] = squa - s*(s+1)/2 - (N - (((i+j)%2 == 0)? j : i));
46                }
47            }
48        /* 打印输出 */   
49        for(i = 0; i < N; i++) {
50            for(j = 0; j < N; j++)
51                printf("%-6d", a[i][j]);
52            printf("/n");
53        }
54        return 0;
55    }
56   
57    void zigzag2(int n)
58    {
59        int **a =(int**) malloc(n*sizeof(int *));  //分配空间
60     
61        if(NULL == a)
62            return ;
63        int i;
64        for(i = 0; i < n; i++) {
65            if((a[i] =(int*) malloc(n * sizeof(int))) == NULL) {
66                while(--i>=0)
67                    free(a[i]);
68                free(a);
69                return;
70            }
71        }
72     
73        bool flag = false; //这个标志位用来判断是从45度角生成还是225度角生成
74        int count = 0;
75        for(i=0; i<n; i++)  //生成的上半部分的数据
76            {
77     
78                if(flag)
79                     {
80                        for(int r = 0; r<=i; r++)
81                            {
82                                a[r][i-r] = count;
83                                count++;
84                            }
85                        flag = false;
86                    }
87                else
88                    {
89                        for(int r = i; r>=0; r--)
90                            {
91                                a[r][i-r] = count;
92                                count++;
93                            }
94                        flag = true;
95                    }
96            }
97        for(i=n-1; i>=0; i--)  //生成的是下半部分的数据
98            {
99                if(flag)
100                    {
101                        for(int r = 0; r<=i-1; r++)
102                            {
103                                int r1 = n-i+r;       //代表当前行
104                                int c1 = 2*n-i-1-r1;  //代表当前列
105                                a[r1][c1] = count;
106                                count++;
107                            }
108                        flag = false;
109                    }
110                else
111                    {
112                        for(int r = i-1; r>=0; r--)
113                            {
114                                int r1 = n-i+r;
115                                int c1 = 2*n-i-1-r1;
116                                a[r1][c1] = count;
117                                count++;
118                            }
119                        flag = true;
120                    }
121            }
122        for(int r = 0; r<n; r++)
123            {
124                for(int c=0; c<n; c++)
125                    printf("%-6d", a[r][c]);
126                printf("/n");
127            }
128    }
129   
130    int main()
131    {
132        int N;
133        scanf("%d", &N);
134        zigzag1(N);
135        cout<<"-------------------"<<endl;
136        zigzag2(N);
137        return 0;
138    }
----------------------------
$ ./a.out
4
0     1     5     6    
2     4     7     12   
3     8     11    13   
9     10    14    15   
----------------------------
0     1     5     6    
2     4     7     12   
3     8     11    13   
9     10    14    15   
----------------------------

<!-- @page { size: 21cm 29.7cm; margin: 2cm } P { margin-bottom: 0.21cm } -->

--------------------------

知识点:

1 )算法 zigzag1 ()利用了沿 45 度线,数组下标 i j 0 1 2 3 ... 递增!并且

利用下标与其值的对应关系得出数组元素的值;

2 )算法 zigzag2 ()直接利用 zigzag 矩阵的特点进行编程实现!浅显易懂!特别注意那个

flag false ;为是否为 225 度角度( true 225 false 45

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用zigzag+varint编码和解码整数的C++示例代码,可以作为参考: ```c++ #include <iostream> #include <vector> // zigzag编码 int32_t zigzag_encode(int32_t n) { return (n << 1) ^ (n >> 31); } // zigzag解码 int32_t zigzag_decode(int32_t n) { return (n >> 1) ^ -(n & 1); } // varint编码 std::vector<uint8_t> varint_encode(uint32_t n) { std::vector<uint8_t> buf; while (n > 0x7f) { buf.push_back((n & 0x7f) | 0x80); n >>= 7; } buf.push_back(n); return buf; } // varint解码 uint32_t varint_decode(const uint8_t* buf, size_t& len) { uint32_t n = 0; size_t shift = 0; while (true) { uint8_t b = buf[len++]; n |= (b & 0x7f) << shift; if (!(b & 0x80)) break; shift += 7; } return n; } // zigzag+varint编码 std::vector<uint8_t> encode(int32_t n) { return varint_encode(zigzag_encode(n)); } // zigzag+varint解码 int32_t decode(const uint8_t* buf, size_t len) { return zigzag_decode(varint_decode(buf, len)); } int main() { int32_t n = -12345; std::vector<uint8_t> encoded = encode(n); size_t len = 0; int32_t decoded = decode(encoded.data(), encoded.size(), len); std::cout << n << " " << encoded.size() << " " << decoded << std::endl; return 0; } ``` 在这个示例中,我们同样定义了zigzag编码和解码函数,以及varint编码和解码函数。不同的是,在varint解码函数中,我们使用引用传递一个长度参数,用于返回解码后数据的长度。然后我们定义了一个zigzag+varint编码和解码函数,它将整数先进行zigzag编码,然后再进行varint编码。在测试中,我们将一个有符号整数编码为zigzag+varint格式,然后解码回原始整数,并输出结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值