如何将一个数组压缩成一个向量并正确地从中读取

How to compress aт array into a vector and properly read from it

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#include <malloc.h>


#define n 6
void insertarray(int arr[n][n])
{  for(int j = 0; j < n; j++){
  if(j==0){
    for (int i = 0; i < n; i++){
      arr[i][j] = rand()%50;
    }
  }
  if(j==1){
    for (int i = 0; i < n; i++){
      if(i==0){
          arr[i][j] = 0;
      }
      else if(i==5){
          arr[i][j] = 0;
      }
      else arr[i][j] = rand()%50;
    }
  }
  if(j==2){
    for (int i = 0; i < n; i++){
      if(i==0 || i==1 || i==4 || i==5){
        arr[i][j] = 0;
      }
      else arr[i][j] = rand()%50;
    }
  }
  if(j==3){
    for (int i = 0; i < n; i++){
      if(i==0 || i==1 || i==4 || i==5){
        arr[i][j] = 0;
      }
      else arr[i][j] = rand()%50;
    }
  }
  if(j==4){
    for (int i = 0; i < n; i++){
      if(i==0){
          arr[i][j] = 0;
      }
      else if(i==5){
          arr[i][j] = 0;
      }
      else arr[i][j] = rand()%50;
    }
  }
  if(j==5){
    for (int i = 0; i < n; i++){
      arr[i][j] = rand()%50;
    }
  }
}

}

int NewIndex(int x, int y)     //пересчет индексов
{   int j=0;
    for(int i=0; i<x; i++) j+= n-i;
    return j+y-x;
}
void Put(int vec [], int x, int y, int v)  // Запись в вектор (сжатие)
{  if (y >=x) vec[NewIndex(x, y)] = v;
}
int Get(int vec [], int x, int y) // Чтение из вектора
{  if (y >=x) return vec[NewIndex(x, y)];
   else return 0;
}

void printarray(int a[n][n])
{    for(int i = 0; i < n; i++)
     {  for (int j = 0; j < n; j++)
    printf("%3i", a[i][j]);
  printf("\n");
     }
}
int main()
{  int vec[n*n/2+n/2];
   int array[n][n];
   insertarray(array);
   printarray(array);
   for(int i = 0; i < n; i++)
     for (int j = 0; j <n ; j++)
         Put(vec, i, j, array[i][j]);   //сжатие массива
   for(int i = 0; i < n*n/2+n/2; i++)   //выдача результата сжатия
  printf("%3i", vec[i]);
    printf("\n\n");
    for(int i = 0; i < n; i++)
    { for (int j = 0; j < n; j++)  //чтение из сжатого представления
       printf("%3i", Get(vec,i,j));
      printf("\n");
     }
    return 0;
}

好吧,我有一个完全有效的代码,它首先创建一个包含主对角线下的空元素的数组,将其压缩成一个向量,然后从中读取。但现在我必须制作一个数组,其中包含在对角线交叉上方和下方的两个三角形中的空元素。 它必须看起来像这样

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

第一步成功了:我生成了这样的数组,但问题是它没有正常压缩它。它需要转换所有不在三角形中的元素,但它压缩就像它只在主对角线下有空元素一样。阅读的问题在于它像过去一样读取数组,但也读取交叉点上方的空元素三角形。你能帮我重做代码吗?我添加了 运行 我的程序的图片

为了实现这个模式,我们测试我们当前的 是在我们当前的 相对于任一边缘的范围内,向上到我们的中途点。然后我们将计算倒过来。

将矩阵与数组相互转换只是遍历矩阵边界、writing/reading to/from 数组并推进数组指针的问题。

要压缩矩阵,我们需要应用计算的逆作为过滤器,仅存储非零值。解压缩遵循与我们最初的 fill 操作相同的逻辑,但取而代之的是从数组中获取。

注意这里计算的大小:

int vec[n*n/2 + n/2];

不会为结果创建大小正确的数组(对于大小 6,这会产生 21,而您至少需要 24)。请查看下面的函数 non_zero_count,以准确计算该模式针对任何给定尺寸生成的非零值的数量。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void fill_matrix(int sz, int m[sz][sz]) {
    for (int i = 0; i < sz; i++) {
        for (int j = 0; j < sz; j++) {
            if ((i <= sz / 2 && j > i && j < sz - 1 - i) ||
                (i > sz / 2 && j > sz - i - 1 && j <= i - 1))
                m[i][j] = 0;
            else
                m[i][j] = rand() % 99 + 1;
        }
    }
}

void pack_matrix(int *array, int sz, int m[sz][sz]) {
    for (int i = 0; i < sz; i++)
        for (int j = 0; j < sz; j++)
            if (!(i <= sz / 2 && j > i && j < sz - 1 - i) &&
                !(i > sz / 2 && j > sz - i - 1 && j <= i - 1))
                *array++ = m[i][j];
}

void unpack_matrix(int *array, int sz, int m[sz][sz]) {
    for (int i = 0; i < sz; i++) {
        for (int j = 0; j < sz; j++) {
            if ((i <= sz / 2 && j > i && j < sz - 1 - i) ||
                (i > sz / 2 && j > sz - i - 1 && j <= i - 1))
                m[i][j] = 0;
            else
                m[i][j] = *array++;
        }
    }
}

void print_matrix(int sz, int m[sz][sz]) {
    for (int i = 0; i < sz; i++) {
        printf("[ ");
        for (int j = 0; j < sz; j++)
            printf("%02d ", m[i][j]);
        printf("]\n");
    }
}

int non_zero_count(int n) {
    int is_even = n % 2 == 0;

    return (n * n) - ((is_even ? n : n - 1) / 2) * (n - (is_even ? 2 : 1));
}

#define MSZ 6
int main(void) {
    int matrix[MSZ][MSZ];
    int matrix2[MSZ][MSZ];
    int array[non_zero_count(MSZ)];

    srand(time(NULL));

    fill_matrix(MSZ, matrix);
    print_matrix(MSZ, matrix);

    puts("----");

    pack_matrix(array, MSZ, matrix);
    unpack_matrix(array, MSZ, matrix2);
    print_matrix(MSZ, matrix2);
}

输出:

[ 59 00 00 00 00 79 ]
[ 91 50 00 00 25 37 ]
[ 24 85 19 23 24 25 ]
[ 67 97 54 14 12 34 ]
[ 44 78 00 00 14 01 ]
[ 25 00 00 00 00 12 ]
----
[ 59 00 00 00 00 79 ]
[ 91 50 00 00 25 37 ]
[ 24 85 19 23 24 25 ]
[ 67 97 54 14 12 34 ]
[ 44 78 00 00 14 01 ]
[ 25 00 00 00 00 12 ]