首先要明白RAID技术的原理
RAID原理:
把数据分成多个数据块,分别存储到d个磁盘中,一个数据块的数据对应s个比特,一个磁盘存储b个数据块。在一个磁盘中数,每隔d-1个数据块有一个校验块,校验块存储的是校验数据,使得每d个数据块(在磁盘间数)的异或结果为全0(偶校验)或全1(奇校验)
举个例子:
d=5, s=2, b=7
6C7A79EDFC6C7A
(0110 1100 0111 1010 0111 1001 1110 1101 1111 1100 0110 1100 0111 1010) 的存储方式如下,红色的是校验块
(最后的两列是我另加的,题目中没有,方便大家理解校验块位置)
假设使用偶校验(E),用 ^ 代表异或运算(C/C++)
第一列为0 ^ 0 ^ 1 ^ 1 ^ 0 = 0,即使少一个也能根据偶校验判断出缺少的是0还是1
需要注意的是:
1.原题中的例子是一列为一个磁盘,然而实际输入是一行为一个磁盘,所以如果用二维数组存储数据,检查每一列是否满足校验就可以了
2.如果一列中丢失的数据块大于1,那么数据无法恢复
3.丢失的数据块位置随机,要考虑到可能是一列中的第一个,所以暂存异或结果的变量不能默认取第一个
4.数据要转换成大写十六进制输出,因为四个二进制位转换成一位,所以如果数据长度不能整除4,要在末尾补0
代码如下:
#include<stdio.h>
#include<string.h>
const int MAX_S = 70;
const int MAX_D = 10;
const int MAX_B = 110;
char data[MAX_D][MAX_S * MAX_B];
char contents[MAX_D * MAX_S * MAX_B]; // 存放二进制数据
int res[MAX_D* MAX_S * MAX_B/4]; //存放十进制数据,方便16进制输出
int flag = 1; // 能否恢复数据
int d, s, b;
char type;
void check(int col) {
int cnt = 0, cnt_x = 0, t, index; // cnt_x是x的个数, index是x的位置
int r = type == 'E' ? 0 : 1;
for(int i = 0; i < d; i++