一:题目

(一)基础知识补充(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. tensorflow API _ 1 (control_flow_ops.cond)

    该函数用来控制程序执行流,相当于if-else了import tensorflow as tffrom tensorflow.python.ops import control_flow_ops a ...

  2. HDU - 4507 - 吉哥系列故事——恨7不成妻(数位DP,数学)

    链接: https://vjudge.net/problem/HDU-4507 题意: 单身! 依然单身! 吉哥依然单身! DS级码农吉哥依然单身! 所以,他生平最恨情人节,不管是214还是77,他都 ...

  3. web实现大文件上传分片上传断点续传

    需求:项目要支持大文件上传功能,经过讨论,初步将文件上传大小控制在500M内,因此自己需要在项目中进行文件上传部分的调整和配置,自己将大小都以501M来进行限制. 第一步: 前端修改 由于项目使用的是 ...

  4. RookeyFrame 删除 线下添加的model

    环境:在model层已经添加了Crm_Cm_ContactInfo2 这个类,这个类现在已经添加到了数据库的,使用之前的方法(在前面的文章有提到该类) 删除步骤: 1.Sys_Module表 的字段 ...

  5. 洛谷 P1714 切蛋糕 题解

    P1714 切蛋糕 题目描述 今天是小Z的生日,同学们为他带来了一块蛋糕.这块蛋糕是一个长方体,被用不同色彩分成了N个相同的小块,每小块都有对应的幸运值. 小Z作为寿星,自然希望吃到的第一块蛋糕的幸运 ...

  6. 洛谷 P2313 [HNOI2005]汤姆的游戏 题解

    P2313 [HNOI2005]汤姆的游戏 题目描述 汤姆是个好动的孩子,今天他突然对圆规和直尺来了兴趣.于是他开始在一张很大很大的白纸上画很多很多的矩形和圆.画着画着,一不小心将他的爆米花弄撒了,于 ...

  7. Java 操作Redis封装RedisTemplate工具类

    package com.example.redisdistlock.util; import org.springframework.beans.factory.annotation.Autowire ...

  8. Nginx模块说明

    一.Nginx内置模块 -–prefix= #指向安装目录 -–sbin-path #指向(执行)程序文件(nginx) -–conf-path= #指向配置文件(nginx.conf) -–erro ...

  9. qt access 数据库

    #include <QCoreApplication> #include <QSqlDatabase> #include <QSqlQuery> #include ...

  10. Column 'status' specified twice

    字段写了两次, 检查下sql语句, 删除一个就好了.