zoukankan      html  css  js  c++  java
  • 稀疏数组-矩阵存储【C语言实现】

    稀疏数组

    /*
     * @Author: itThree
     * @Date: 2021-09-10 15:48:10
     * @LastEditTime: 2021-09-15 15:58:50
     * @Description: 
     * @FilePath: cppdatassparseArr.cpp
     * 光阴之逆旅,百代之过客,而已
     */
    
    #include<stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    void printArr(int *arr, int row, int col);
    
    /**
     * 稀疏数组:将二维数组进行“压缩”;
     * 使用n+1行3列,其中n为原数组中有效(非零)元素个数,稀疏数组第0行用于存放行、列、元素总数信息故需n+1行
    */
    
    //统计数组中元素的个数,用于确定稀疏数组的行数
    int countElement(int* &p, int row, int col){
        int sum;
        int n = row*col;
        for(int i=0; i<n; i++){
            if(*(p+i) != 0){
                sum++;
            }
        }
        printf("sum:	%d
    ",sum);
        return sum;
    
    }
    
    //以指针形式接收矩阵(二维数组)
    void createSparseArr2(int* arr, int row, int col ,int n){
        int sparse[n+1][3];
        sparse[0][0] = row;
        sparse[0][1] = col;
        sparse[0][2] = n;
        int sparseRow = 0;
        for(int i=0;i<row;i++){
            for(int j=0;j<col;j++){
                if(*(arr+i*col+j)!=0){
                   sparseRow++;
                   sparse[sparseRow][0] = i;
                   sparse[sparseRow][1] = j;
                   sparse[sparseRow][2] = *(arr+i*col+j);
               }
            }            
        }
        printArr((int*)sparse,n+1,3);
    }
    //这个稀疏数组的存储算法为n^2,还可用指针实现一个n。
    
    
    //打印二维数组
    void printArr(int *arr, int row, int col)
    {//指针指向二维数组首地址,依靠row,col判别边界条件
        //遍历行
        for(int i=0;i<row;i++){
            //遍历列
            for(int j=0;j<col;j++)printf("%d 	",*(arr+i*col+j));
            printf("
    ");
        }
    
    }
    
    int main(){
        int source[4][8]{
            {1,7,6,5,2,8,2,8},
            {2,7,6,5,2,8,2,8},
            {3,7,6,5,2,8,2,8},
            {4,7,6,5,2,8,2,8}
        };
        int* p;
        p = source[0];
        int n = countElement(p,4,8);
        printf("-------------------------------------------
    ");
        
        createSparseArr2((int*)source,4,8,n);
        //int* i[4];
        //指针i指向二维数组的一行
        //i[0] = source[0];
        //i[1] = source [1];
        //i[2] = source [2];
        //i[3] = source [3];
        // createSparseArr1(i,4,8,n);
        return 0;
    }
    
    

    使用指针数组方式创建稀疏数组

    //使用指针数组传值
    void createSparseArr1(int* p1[], int row, int col, int n){
        //需要多一行来存储原数组大小信息
        int sparse[n+1][3];
        sparse[0][0] = row;
        sparse[0][1] = col;
        sparse[0][2] = n;
        //控制稀疏数组的行号
        int sparseRow = 0;
        for (int i = 0; i < row; i++)
       {
           for (int j = 0; j < col; j++)
           {    //原数数组索引处有无元素为判断条件,有则放入稀疏数组,无则进行下一次循环
               if(p1[i][j]!=0){
                   //第0行已存放数据,故先行++
                   sparseRow++;
                   sparse[sparseRow][0] = i;
                   sparse[sparseRow][1] = j;
                   sparse[sparseRow][2] = p1[i][j];
               }
           }
           
       }
        printArr((int*)sparse,n+1,3);
    }
    

    遇到的问题:

    强制转换数组首地址为指针返回不可行

    image-20210915152000718

    报错的地方:

    int sparse[n+1][3];
    return (int*) sparse;
    

    解答:在函数执行完毕并return后sparse数组将被销毁,故无法将其强制转换为指针类型并返回;

    不过,指定一个指针指向sparse并返回倒不成问题。

    指针与数组地址

    int source[4][8]{
            {1,7,6,5,2,8,2,8},
            {2,7,6,5,2,8,2,8},
            {3,7,6,5,2,8,2,8},
            {4,7,6,5,2,8,2,8}
        };
        int* p;
        p = source[0];
        int* i[4];
        //指针i指向二维数组的一行
        i[0] = source[0];
        i[1] = source [1];
        i[2] = source [2];
        i[3] = source [3];
    //得出结果
    	// source[0],source[0][0]在同一地址下
     	printf("p:	%d
    ", p);
        printf("source[0]:	%d
    ", source[0]);
        printf("&source[0][0]:	%d
    ", &source[0][0]);
        printf("source[0][0]:	%d
    ", source[0][0]);
        printf("*p:	%d
    ", *p);
    	//使用指针数组指向二维数组每行首地址可行
        printf("i[1][i]:	%d
    ", i[1][2]);
    	
        printf("*(p+31)	%d
    ", *(p+31));
    	//下标溢出了哦!
        printf("*(p+32)	%d
    ", *(p+32));
    

    运行结果:image-20210915153230219

  • 相关阅读:
    [JSOI2008]Blue Mary开公司[李超线段树]
    线段树分治
    满汉全席[2-SAT]
    「一本通 3.5 练习 5」和平委员会
    2-SAT问题
    2019/04/06 BJ省选模拟DAY1
    构造题【随时更
    文本编辑器vim/vi——命令模式
    指令——cat
    指令——history
  • 原文地址:https://www.cnblogs.com/MR---Zhao/p/15289264.html
Copyright © 2011-2022 走看看