You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改C语言代码实现含上下对角零三角数组的向量压缩与读取

特殊对称零三角矩阵的压缩存储适配修改

问题背景

原有代码的压缩逻辑是适配主对角线下方全零的上三角矩阵,对应规则是仅当矩阵位置满足j >=i(列序号大于等于行序号)时存储非零值,其余位置返回0。
现在需要适配的特殊矩阵结构为:主对角线两侧对称分布的嵌套三角区域为固定零值,非零区域为左右两个三角的并集,以n=6为例的矩阵结构如下:

6 0 0 0 0 2
3 1 0 0 4 3 
2 9 2 1 5 6
7 8 6 2 4 6
8 7 0 0 2 1
9 0 0 0 0 9

由于原有索引映射、存储、读取逻辑没有匹配新的非零区域规则,会出现压缩错位、还原矩阵错误的问题。

核心适配思路

  • 先明确所有非零位置的判定规则:对于任意行号x(从0开始计数),先计算两个边界值:
    • 左边界lb = min(x, n-1 -x):该行从第0列到lb列的区域为左侧非零区
    • 右边界hb = max(x, n-1 -x):该行从hb列到最后一列的区域为右侧非零区
    • 落在lb < j < hb区间内的位置为固定零值,不需要存入压缩向量
  • 重新计算压缩向量的索引偏移:逐行累计前面所有行的非零元素总数作为基础偏移,再计算当前行内的元素偏移,得到二维位置对应的一维向量索引。
  • 调整存储、读取逻辑:仅对非零区域的位置执行向量读写,零区域直接返回固定零值,跳过存储。

关键代码修改

1. 重写索引计算函数NewIndex

替换原有仅累计上三角元素的逻辑,改为逐行累计实际非零元素数,计算行内偏移:

int NewIndex(int x, int y) {
    int total_offset = 0;
    const int n_minus_1 = n - 1;
    // 累计前面所有行的非零元素数,作为偏移基数
    for (int i = 0; i < x; i++) {
        int row_lb = (i < n_minus_1 - i) ? i : (n_minus_1 - i);
        int row_hb = (i > n_minus_1 - i) ? i : (n_minus_1 - i);
        int left_cnt = row_lb + 1;
        int right_cnt = n - row_hb;
        total_offset += left_cnt + right_cnt;
    }
    // 计算当前行内的元素偏移
    int cur_lb = (x < n_minus_1 - x) ? x : (n_minus_1 - x);
    int cur_hb = (x > n_minus_1 - x) ? x : (n_minus_1 - x);
    int row_offset;
    if (y <= cur_lb) {
        row_offset = y;
    } else {
        row_offset = (cur_lb + 1) + (y - cur_hb);
    }
    return total_offset + row_offset;
}

2. 调整压缩存储函数Put

替换原有y >=x的判断条件,按新的非零区域规则执行写入:

void Put(int vec [], int x, int y, int v) {
    const int n_minus_1 = n - 1;
    int cur_lb = (x < n_minus_1 - x) ? x : (n_minus_1 - x);
    int cur_hb = (x > n_minus_1 - x) ? x : (n_minus_1 - x);
    // 仅非零区域的值需要写入压缩向量
    if (y <= cur_lb || y >= cur_hb) {
        vec[NewIndex(x, y)] = v;
    }
}

3. 调整向量读取函数Get

匹配非零区域规则,零区域直接返回0:

int Get(int vec [], int x, int y) {
    const int n_minus_1 = n - 1;
    int cur_lb = (x < n_minus_1 - x) ? x : (n_minus_1 - x);
    int cur_hb = (x > n_minus_1 - x) ? x : (n_minus_1 - x);
    // 中间零区域直接返回固定0
    if (y > cur_lb && y < cur_hb) {
        return 0;
    }
    return vec[NewIndex(x, y)];
}

4. 调整压缩向量的容量

原有向量容量是按上三角矩阵计算的,会出现数组越界,需要按实际非零元素总数分配空间:

// 辅助函数:计算压缩向量需要的总长度
int calc_vec_size() {
    int total = 0;
    const int n_minus_1 = n -1;
    for (int i=0; i<n; i++) {
        int row_lb = (i < n_minus_1 -i) ? i : (n_minus_1 -i);
        int row_hb = (i > n_minus_1 -i) ? i : (n_minus_1 -i);
        total += (row_lb +1) + (n - row_hb);
    }
    return total;
}
// 主函数中的vec定义替换为:
int vec[calc_vec_size()];

修改后的运行效果

  • 压缩过程自动跳过所有零区域,仅存储实际非零值,向量长度没有冗余
  • 读取过程自动还原所有零位置,输出的矩阵和生成的原始特殊矩阵完全一致,不存在索引错位

内容的提问来源于stack exchange,提问作者user15199447

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 18:27:04