#include #include #define N 10 // 定义数组大小为10,包括占位符0 // 计算一个整数在二进制中需要的位数 int length(int i) { int k = 1; // 初始化位数计数器 i = i / 2; // 将整数除以2,开始计算 while (i > 0) { // 当i大于0时继续 k++; // 每次循环位数增加1 i = i / 2; // 继续除以2 } return k; // 返回计算得到的位数 } // 压缩函数,计算最优分段 void Compress(int n, int p[], int s[], int l[], int b[]) { int Lmax = 256, header = 11; // 定义最大段数和头部长度 s[0] = 0; // 初始化s数组 // 遍历实际数据,不包括第一个元素 for (int i = 1; i <= n; i++) { b[i] = length(p[i]); // 计算当前元素的位数 int bmax = b[i]; // 记录当前最大位数 s[i] = (i > 1 ? s[i - 1] : 0) + bmax + header; // 计算当前段的最小存储长度 l[i] = 1; // 初始段数为1 printf("mid==%d\n",s[i]); // 遍历可能的段数 for (int j = 2; j <= i && j <= Lmax; j++) { // 更新最大位数 printf("bmax前**=%d",bmax); if (bmax < length(p[i - j + 1])) { bmax = length(p[i - j + 1]); printf("bmax后**=%d",bmax); } // 判断是否需要更新存储长度 printf("\nmid=%d\n",s[i - j] + j * bmax + header); if (s[i] > s[i - j] + j * bmax + header) { s[i] = s[i - j] + j * bmax + header; // 更新最小存储长度 l[i] = j; // 更新段数 b[i] = bmax; // 更新位数 // printf("s[i]=%d,mid=%d\n",s[i],s[i - j] + j * bmax + header); } } // 输出当前组的信息 printf("组 %d: L = %d, B = %d, S = %d\n", i, l[i], b[i], s[i]); } } // 追溯函数,恢复最优分段信息 int TraceBack(int n, int l[], int b[]) { int i = 0; int temp_l[N], temp_b[N]; // 临时数组存储分段信息 // 从最后一个元素向前追溯 while (n >= 1) { // 只从1开始追溯,跳过0 temp_l[i] = l[n]; // 记录段数 temp_b[i] = b[n]; // 记录位数 n = n - l[n]; // 更新n,向前移动 i++; // 增加索引 } // 反转数组,恢复正确顺序 for (int j = 0; j < i; j++) { b[j] = temp_b[i - j - 1]; // 反向赋值位数 l[j] = temp_l[i - j - 1]; // 反向赋值段数 } return i; // 返回段数 } // 输出函数,展示最终结果 void Out(int m, int min_len, int l[], int b[], int p[]) { printf("最小长度:%d\n", min_len); // 输出最小存储长度 printf("共分成:%d段\n", m); // 输出段数 int index = 1; // 从1开始,跳过0 for (int i = 0; i < m; i++) { // 输出每段的信息 printf("第%d段含有%d元素. 需要存储位数%d,", i + 1, l[i], b[i]); printf("元素值:"); // 输出当前段的元素值 for (int j = 0; j < l[i]; j++) { printf("%d ", p[index++]); // 逐个输出元素,跳过第一个0 } printf("\n"); // 换行 } } // 主函数,程序入口 int main() { int p[] = {0, 4, 6, 5, 7, 129, 138, 1, 2, 3}; // 输入的灰度序列(加了0) int s[N] = {0}, l[N] = {0}, b[N] = {0}; // 初始化存储长度、段数和位数的数组 // 输出输入序列 printf("图像的灰度序列为:\n"); for (int i = 0; i < N; i++) { printf("%d ", p[i]); } printf("\n"); // 调用压缩函数 Compress(N - 1, p, s, l, b); int m = TraceBack(N - 1, l, b); // 调用追溯函数获取段数 Out(m, s[N - 1], l, b, p); // 输出结果 return 0; }