算法习题---4-7RAID技术(UV509)
一:题目
(一)基础知识补充(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)的更多相关文章
- DSP算法学习-过采样技术
DSP算法学习-过采样技术 彭会锋 2015-04-27 23:23:47 参考论文: 1 http://wr.lib.tsinghua.edu.cn/sites/default/files/1207 ...
- 【算法习题】数组中任意2个(3个)数的和为sum的组合
题1.给定一个int数组,一个数sum,求数组中和为sum的任意2个数的组合 @Test public void test_find2() { int[] arr = { -1, 0, 2, 3, 4 ...
- 阿里巴巴算法工程师四面(三轮技术+hr面)详细面经
阿里面试总结: 一遍一遍地刷阿里网站,今天发现“面试中”变成“待跟进offer”了,写个面经攒人品,希望offer通知邮件早点来吧. 我当时投简历时投了C/C++工程师,其实也没经过啥考虑,因为我一开 ...
- paper 153:Delaunay三角剖分算法--get 这个小技术吧!
直接摘自百度百科,希望大家能根据下面的介绍稍微理顺思路,按需使用,加油! 解释一下:点集的三角剖分(Triangulation),对数值分析(比如有限元分析)以及图形学来说,都是极为重要的一项预处理技 ...
- July 算法习题 - 字符串4(全排列和全组合)
https://segmentfault.com/a/1190000002710424 思想:当前层各节点首元素不同,则各节点的剩余元素也不同:下一层节点交换范围为首元素以外的元素 全排列算法: vo ...
- Opencv-Python项目(1) | 基于meanshiftT算法的运动目标跟踪技术学习
目标跟踪(object tracking)就是在连续的视频序列中,建立所要跟踪物体的位置关系,得到物体完整的运动轨迹. 目标跟踪分为单目标跟踪和多目标跟踪.本文如无特别指出,均指单目标跟踪. 通常的做 ...
- 算法习题---4-9数据挖掘(Uva1591)
一:题目 这是最懵逼的一道题,什么鬼......... [刷题]算法竞赛入门经典(第2版) 4-9/UVa1591 - Data Mining(详细题目看这个吧,不想多说) 二:代码实现 #defin ...
- tarjan算法 习题
dfs树与tarjan算法 标签(空格分隔): 517coding problem solution dfs树 tarjan Task 1 给出一幅无向图\(G\),在其中给出一个dfs树\(T\), ...
- 【算法习题】正整数数组中和为sum的任意个数的组合数
1.递归实现(参考:https://blog.csdn.net/hit_lk/article/details/53967627) public class Test { @org.junit.Test ...
随机推荐
- 结构型模式(一) 适配器模式(Adapter)
一.动机(Motivation) 在软件系统中,由于应用环境的变化,常常需要将"一些现存的对象"放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的. 如何应对这种&q ...
- Redis面试基本问题
Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet.如果你是Redis中高级用户,还需要加上下面几种数据结构HyperLogLog.Ge ...
- ES的入门学习
ES的入门:ES的雇员文档的设计和实现功能 ES的存放中包括:索引,类型,文档,字段 PUT /megacorp/employee/1{{ "first_name" : " ...
- LeetCode 364. Nested List Weight Sum II
原题链接在这里:https://leetcode.com/problems/nested-list-weight-sum-ii/description/ 题目: Given a nested list ...
- ArrayList 集合的几种遍历的方法
ArrayList 集合 也可称作动态数组(长度可变),在新建的时候是没有默认长度的,在新增数据长度小于10的时候,ArrayList 的长度会自动设置为10 //了解更多可以按住Ctrl 再点击你 ...
- C++中unique函数的用法总结
个人感觉,unique是STL中很实用的函数之一,需要#include,下面来简单介绍一下它的作用. unique的作用是"去掉"容器中相邻元素的重复元素,这里去掉要加一个引号,为 ...
- 贴一段Matlab代码
% reduce leading zeros with rx ind3= find(rx~=0, 1, 'first'); if (isempty(ind3)) rx= gf(0, m, f0); e ...
- 原创:ThreadPoolExecutor线程池深入解读(一)----原理+应用
本文档,适合于对多线程有一定基础的开发人员.对多线程的一些基础性的解读,请参考<java并发编程>的前5章. 对于源代码的解读,本人认为可读可不读.如果你想成为一位顶级的程序员,那就培养自 ...
- Coupled和segregated【转载】
转载自:http://blog.sina.com.cn/s/blog_67873f6c0100ltq6.html 问题1: 我看中文帮组里说是'分离'的意思?我绝对翻译不太好,请问有更好的翻译吗? 和 ...
- JavaWeb之基础(2) —— HTTP协议
1. 粗讲什么是HTTP协议 HTTP协议的全程是Hyper Text Transfer Protocol,超文本传输协议,见名知意,这是个用来控制传输超文本的协议.下面就来简单说说什么是HTTP协议 ...