题目——压缩技术

原题目地址:

https://www.luogu.com.cn/problem/P1320

题目描述

设某汉字由 N * N 的 0 和 1 的点阵图案组成。

我们依照以下规则生成压缩码。连续一组数值:从汉字点阵图案的第一行第一个符号开始计算,按书写顺序从左到右,由上至下。第一个数表示连续有几个 0,第二个数表示接下来连续有几个 1,第三个数再接下来连续有几个 0,第四个数接着连续几个 1,以此类推……

例如: 以下汉字点阵图案:

0001000
0001000
0001111
0001000
0001000
0001000
1111111

对应的压缩码是:7 3 1 6 1 6 4 3 1 6 1 6 1 3 7 (第一个数是 N ,其余各位表示交替表示0和1 的个数,压缩码保证 N * N 交替的各位数之和)

输入格式

汉字点阵图(点阵符号之间不留空格)。

输出格式

输出一行,压缩码。

样例 #1

样例输入 #1

0001000
0001000
0001111
0001000
0001000
0001000
1111111

样例输出 #1

7 3 1 6 1 6 4 3 1 6 1 6 1 3 7

提示

数据保证,3 <= N <= 200。

我的代码

#include<stdio.h>
#include<string.h>
/*定义最大长度,长度,存储所有数字的列表*/
#define MAX 203
int numlen;
char arr[MAX][MAX];
/*读取每一行,并返回长度的函数*/
void read_number();
/*计算并打印压缩码的函数*/
void number_count();

void read_number(){
    char str[MAX];
    int hang = 0; //定义行数(初始为1)
    fgets(str, MAX, stdin);//包括换行符
    numlen = strlen(str) - 1;//获得长度
  

    //把点阵图案第一排复制到arr列表中
    for(int i = 0; i < numlen; i++){
        arr[hang][i] = str[i];
    }
    hang++;

    while(hang < numlen){
        fgets(str, MAX, stdin);//读入新的一行,行数为hang
        for(int i = 0; i < numlen; i++){
            arr[hang][i] = str[i];
        }
        hang++;
    }
    //该函数任务完成
}

void number_count(){
    int sum = 0;//定义连续次数
    int temp = '0';//上一个数字,第一个一定为0
    int num;//正在读取的数字

    for(int i = 0; i < numlen; i++){
        for(int j = 0; j < numlen; j++){
            num = arr[i][j];
            //比较该数字与上一个数字是否相等
            if(num == temp){
                sum++;
            } else {
                printf("%d ", sum);
                temp = num;
                sum = 1;
            }
        }
    }

    printf("%d", sum);
}



int main(){
    read_number();

    printf("%d ", numlen);//输出长度

    number_count();

    return 0;
}

代码分析

  1. 头文件和宏定义部分

    • #include<stdio.h>:引入标准输入输出库,用于输入输出操作,如 fgetsprintf等函数。

    • #include<string.h>:引入字符串处理库,用于获取字符串长度等操作,如 strlen函数。

    • #define MAX 203:定义一个宏常量 MAX,值为 203,用于限制输入字符串的最大长度和二维数组的大小。

  2. 变量和函数声明部分

    • int numlen;:定义一个全局整数变量,用于存储输入数据的长度。

    • char arr[MAX][MAX];:定义一个二维字符数组,用于存储输入的字符数据。

    • void read_number();:声明一个名为 read_number的函数,用于读取用户输入并存储到二维数组中。

    • void number_count();:声明一个名为 number_count的函数,用于统计并输出二维数组中连续相同字符的出现次数。

  3. 函数定义部分

    • read_number函数:

      • char str[MAX];:在函数内部定义一个字符数组,用于临时存储每次读取的一行输入。

      • int hang = 0;:定义一个变量表示行数,初始值为 0。

      • fgets(str, MAX, stdin);:从标准输入读取一行字符,存储到 str数组中。

      • numlen = strlen(str) - 1;:计算第一行输入的长度,不包括换行符。

      • 第一个循环将第一行输入复制到二维数组的第一行。

      • while(hang < numlen)循环:继续读取输入,直到行数达到输入的长度,每次将新行存储到二维数组中。

    • number_count函数:

      • int sum = 0;:定义一个变量用于统计连续相同字符的出现次数,初始值为 0。

      • int temp = '0';:定义一个变量表示上一个数字,初始值为字符 ‘0’。

      • int num;:定义一个变量用于存储当前正在读取的数字。

      • 两个嵌套的循环遍历二维数组中的每个字符。

      • 如果当前字符与上一个字符相同,增加 sum的值;否则,输出当前的 sum值,更新 temp为当前字符,将 sum重置为 1。

      • 最后输出最后一次统计的 sum值。

  4. 主函数部分

    • read_number();:调用 read_number函数读取用户输入并存储到二维数组中。

    • printf("%d ", numlen);:输出输入数据的长度。

    • number_count();:调用 number_count函数统计并输出二维数组中连续相同字符的出现次数。