一:题目

(一)基础知识补充(RAID和奇偶校验)

磁盘管理—磁盘阵列(RAID)实例详解(本题目常用RAID 5技术实现)

奇偶校验(同行数据中同位上的1的个数,偶校验时:1的个数为偶数则校验结果为0,否则为1,奇校验时相反:1的个数为偶数则校验结果为1,否则为0)

(二)题目详解

RAID技术用多个磁盘保存数据。每份数据在不止一个磁盘上保存,因此在某个磁盘损
坏时能通过其他磁盘恢复数据。本题讨论其中一种RAID技术。数据被划分成大小
为s(≤s≤)比特的数据块保存在d(≤d≤)个磁盘上,如图所示,每d-1个数据块都
有一个校验块,使得每d个数据块的异或结果为全0(偶校验)或者全1(奇校验)。

(三)案例解析

例如,d=,s=,偶校验,数据6C7A79EDFC(二进制01101100    )的保存方式如图所示

其中加粗块是校验块。输入d、s、b、校验的种类(E表示偶校验,O表示奇校验)以及b(≤b≤)个数据块(其中“x”表示损坏的数据),
你的任务是恢复并输出完整的数据。如果校验错或者由于损坏数据过多无法恢复,应报告磁盘非法。

(四)样例输入

注意:

其中样例输入中:第一组数据网站和书籍有所出入。自己检查后发现书上是可以的。所以将原来的

替换为:

样例输入:

  5  //第一个参数是磁盘块(将一个数据块拆分为多个分别存放在各个磁盘块中)--列数  第二个参数是每个磁盘块存放的数据位数  第三个参数是数据块数(将每一块数据拆分为多个分别存放在各个磁盘中)--行数
E     //E是偶校验 O是奇校验
E xx11011111 O 11xxx
x1111
0  //0代表输入结束

注意点:

、校验块是不加入十六进制运算的
、校验块的顺序是第一行的第一块,第二行的第二个,到了某行最后一个时,下一行就有从第一个开始算做校验块 ----- 当前行数%列数
、十六进制转换是 一个十六进制数字需要四个二进制数字,所以每四位二进制就是一位十六进制
校验进行是一行中每个块的相同位进行校验
、奇校验就是每个数互相异或下来是1,偶校验就是0
、磁盘不合理有三种可能性:一是已知的位校验不符合,二是未知位有多位,无法判断其内容,三是校验位中含有x

数据实际存放样式:

E

    ----->      
E                      

 ---->
xx11011111 xx
O

11xxx        ----->     11xxx x1111
x1111

(五)样例输出

Disk set  is valid, contents are: 6C7A79EDFC
Disk set is invalid.
Disk set is valid, contents are: FFC

二:代码实现

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string> #define ROW 100 //最多100条 100行
#define COL 6 //最多6个磁盘 6列
#define BITS 64 //每个磁盘块最多64位 int col, row, bits;
char DISK[ROW][COL][BITS], ct; //获取基本数据:磁盘数据和校验类型
char Ddata[COL][BITS], CkCode[BITS]; //获取每行数据和校验值 //-1无效 0结束 1正确

获取磁盘数据,并进行检测和纠错

int getDiskData()    //改进:在这里检错
{
int flag = ;
int x_bits[BITS], xNum = , OneNum[BITS]; //记录x位置x_bits中内容是对于列数值和x的个数
scanf("%d", &col);
if (col == ) return ;
scanf("%d %d", &bits, &row);
getchar();
scanf("%c", &ct);
getchar(); //获取磁盘数据
for (int i = ; i < row;i++)
{
memset(x_bits, -, sizeof(x_bits));
memset(OneNum, , sizeof(OneNum));
for (int j = ; j < col; j++)
{
for (int k = ; k < bits; k++)
{
scanf("%c", &DISK[i][j][k]);
if (DISK[i][j][k] == '\n')
{
k--;
continue;
}
if (i%col == j) //不允许校验位为x
{
if (DISK[i][j][k] == 'x')
flag = -;
} if (DISK[i][j][k] == 'x')
{
if (x_bits[k] != -) //不允许在同一位出现多个x
flag = -;
x_bits[k] = j; //最多记录不同位上的x位置
}
if (i%col !=j && DISK[i][j][k] == '')
OneNum[k]++;
}
}
//复制校验位
memcpy(CkCode, DISK[i][i%col], BITS);
for (int k = ; k < bits;k++) //将对应位置上的数据进行纠错
{
if (x_bits[k] != -) //该行有x数据,需要纠错(纠错就避免了检错)
{
if (ct == 'E') //偶校验
{
if ((CkCode[k] == ''&&OneNum[k] % == ) || (CkCode[k] == '' && OneNum[k] % == ))
DISK[i][x_bits[k]][k] = '';
else
DISK[i][x_bits[k]][k] = '';
}
else //奇校验
{
if ((CkCode[k] == ''&&OneNum[k] % == ) || (CkCode[k] == '' && OneNum[k] % == ))
DISK[i][x_bits[k]][k] = '';
else
DISK[i][x_bits[k]][k] = '';
}
}
else //该行没有x数据,直接检错
{
if (ct == 'E' && ((CkCode[k] == ''&&OneNum[k] % == ) || (CkCode[k] == '' && OneNum[k] % == )))
flag = -;
if (ct == 'O' && ((CkCode[k] == ''&&OneNum[k] % == ) || (CkCode[k] == '' && OneNum[k] % == )))
flag = -;
}
}
}
getchar();
return flag;
}

将字符串二进制转为16进制输出

//转换16进制输出
void printValidData()
{
int n = ;
int m;
//获取每一行数据,进行输出
for (int i = ; i < row; i++)
{
m = ;
for (int j = ; j < col; j++)
{
if (i%col==j) continue; //跳过校验位
for (int k = ; k < bits; k++)
{
if (DISK[i][j][k] == '')
n |= 0x01;
else
n |= 0x00;
m++;
if (m == )
{
printf("%X", n);
n = , m = ;
}
n <<= ;
}
}
//获取完一行
if (m > && m != )
{
m++;
while (m != )
{
n |= 0x00,n <<= ;
m++;
}
printf("%X", n);
}
}
printf("\n");
}

主函数

void main()
{
int c = , flag;
FILE* fp = freopen("data7.in", "r", stdin);
freopen("data7.out", "w", stdout); while (!feof(fp))
{
flag = getDiskData();
if (flag == ) break;
if (flag == -)
printf("Disk set %d is invalid.\n",c++);
else
{
printf("Disk set %d is valid, contends are: ",c++);
printValidData();
}
} freopen("CON", "r", stdin);
freopen("CON", "w", stdout);
}

算法习题---4-7RAID技术(UV509)的更多相关文章

  1. DSP算法学习-过采样技术

    DSP算法学习-过采样技术 彭会锋 2015-04-27 23:23:47 参考论文: 1 http://wr.lib.tsinghua.edu.cn/sites/default/files/1207 ...

  2. 【算法习题】数组中任意2个(3个)数的和为sum的组合

    题1.给定一个int数组,一个数sum,求数组中和为sum的任意2个数的组合 @Test public void test_find2() { int[] arr = { -1, 0, 2, 3, 4 ...

  3. 阿里巴巴算法工程师四面(三轮技术+hr面)详细面经

    阿里面试总结: 一遍一遍地刷阿里网站,今天发现“面试中”变成“待跟进offer”了,写个面经攒人品,希望offer通知邮件早点来吧. 我当时投简历时投了C/C++工程师,其实也没经过啥考虑,因为我一开 ...

  4. paper 153:Delaunay三角剖分算法--get 这个小技术吧!

    直接摘自百度百科,希望大家能根据下面的介绍稍微理顺思路,按需使用,加油! 解释一下:点集的三角剖分(Triangulation),对数值分析(比如有限元分析)以及图形学来说,都是极为重要的一项预处理技 ...

  5. July 算法习题 - 字符串4(全排列和全组合)

    https://segmentfault.com/a/1190000002710424 思想:当前层各节点首元素不同,则各节点的剩余元素也不同:下一层节点交换范围为首元素以外的元素 全排列算法: vo ...

  6. Opencv-Python项目(1) | 基于meanshiftT算法的运动目标跟踪技术学习

    目标跟踪(object tracking)就是在连续的视频序列中,建立所要跟踪物体的位置关系,得到物体完整的运动轨迹. 目标跟踪分为单目标跟踪和多目标跟踪.本文如无特别指出,均指单目标跟踪. 通常的做 ...

  7. 算法习题---4-9数据挖掘(Uva1591)

    一:题目 这是最懵逼的一道题,什么鬼......... [刷题]算法竞赛入门经典(第2版) 4-9/UVa1591 - Data Mining(详细题目看这个吧,不想多说) 二:代码实现 #defin ...

  8. tarjan算法 习题

    dfs树与tarjan算法 标签(空格分隔): 517coding problem solution dfs树 tarjan Task 1 给出一幅无向图\(G\),在其中给出一个dfs树\(T\), ...

  9. 【算法习题】正整数数组中和为sum的任意个数的组合数

    1.递归实现(参考:https://blog.csdn.net/hit_lk/article/details/53967627) public class Test { @org.junit.Test ...

随机推荐

  1. js数组的操作大全

    用 js有很久了,但都没有深究过js的数组形式.偶尔用用也就是简单的string.split(char).这段时间做的一个项目,用到数组的地方很多,自以为js高手的自己居然无从下手,一下狠心,我学!呵 ...

  2. Django --- ORM表查询

    目录 使用数据库之前的配置工作 单表操作常用的方法 一对多字段的增删改查 多对多字段数据的增删改查 跨表查询 聚合函数 分组查询 F与Q查询 使用数据库之前的配置工作 settings.py中的配置 ...

  3. python 之类、self

    类是什么 可以视为种类或者类型的同义词.所有的对象都属于某一个类,称为类的实例. 例如:鸟就是"鸟类"的实例.这就是一个有很多子类的一般(抽象)类:看到的鸟可能属于子类" ...

  4. PHP流程控制之for循环控制语句

    王同学反复往返与北京和大连,并且在本上记录往返次数.在PHP中还有另外一种实现方式能够实现同样的计数.无锡大理石测量平台 for 循环是 PHP 中的一种计数型循环,它的语法比较数活多变.这是一个必须 ...

  5. learning java AWT Dialog

    import java.awt.*; public class DialogTest { Frame f = new Frame("test"); Dialog d1 = new ...

  6. C# 分割字符串 分隔符是字符串的情况

    string[] arr = System.Text.RegularExpressions.Regex.Split(str, "\r\n");

  7. 洛谷 P1613 跑路 题解

    P1613 跑路 题目描述 小A的工作不仅繁琐,更有苛刻的规定,要求小A每天早上在6:00之前到达公司,否则这个月工资清零.可是小A偏偏又有赖床的坏毛病.于是为了保住自己的工资,小A买了一个十分牛B的 ...

  8. Docker与Tomcat:去掉项目名称进行访问

    今天搭建了一个solo博客,想要去掉路径后的/solo 首先尝试了最简单的更改tomcat配置文件:server.xml <Context path="/" docBase= ...

  9. 利用iterm2,在命令行预览图片,服务器也是可以的

    1.首先你本地电脑上要安装iterm2软件,我们这里使用brew安装 这个是一定要装的,因为能在命令行渲染出图片文件全靠它,其实不是服务器渲染出来的,而是iterm2 官方网站:https://www ...

  10. 一个想要拥有正常的F1~F12的联想小新潮

    联想如何切换至正常的F1~F12 Fn+Fx的生活让我疲倦,实在难受,就开始了尝试关闭Fn 问题一:无法打开BIOS设置界面 重启,在开机界面时,按F2???顺利开机-(相较于台式机开机时,可以按F2 ...