一:题目

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

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

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

(二)题目详解

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

(三)案例解析

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

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

(四)样例输入

注意:

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

样例输入:

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

注意点:

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

数据实际存放样式:

  1. E
  2.  
  3. ----->
  1. E
  2.  
  3. ---->
  4. xx11011111 xx
  1. O
  2.  
  3. 11xxx -----> 11xxx x1111
  4. x1111

(五)样例输出

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

二:代码实现

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

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

  1. int getDiskData() //改进:在这里检错
  2. {
  3. int flag = ;
  4. int x_bits[BITS], xNum = , OneNum[BITS]; //记录x位置x_bits中内容是对于列数值和x的个数
  5. scanf("%d", &col);
  6. if (col == ) return ;
  7. scanf("%d %d", &bits, &row);
  8. getchar();
  9. scanf("%c", &ct);
  10. getchar();
  11.  
  12. //获取磁盘数据
  13. for (int i = ; i < row;i++)
  14. {
  15. memset(x_bits, -, sizeof(x_bits));
  16. memset(OneNum, , sizeof(OneNum));
  17. for (int j = ; j < col; j++)
  18. {
  19. for (int k = ; k < bits; k++)
  20. {
  21. scanf("%c", &DISK[i][j][k]);
  22. if (DISK[i][j][k] == '\n')
  23. {
  24. k--;
  25. continue;
  26. }
  27. if (i%col == j) //不允许校验位为x
  28. {
  29. if (DISK[i][j][k] == 'x')
  30. flag = -;
  31. }
  32.  
  33. if (DISK[i][j][k] == 'x')
  34. {
  35. if (x_bits[k] != -) //不允许在同一位出现多个x
  36. flag = -;
  37. x_bits[k] = j; //最多记录不同位上的x位置
  38. }
  39. if (i%col !=j && DISK[i][j][k] == '')
  40. OneNum[k]++;
  41. }
  42. }
  43. //复制校验位
  44. memcpy(CkCode, DISK[i][i%col], BITS);
  45. for (int k = ; k < bits;k++) //将对应位置上的数据进行纠错
  46. {
  47. if (x_bits[k] != -) //该行有x数据,需要纠错(纠错就避免了检错)
  48. {
  49. if (ct == 'E') //偶校验
  50. {
  51. if ((CkCode[k] == ''&&OneNum[k] % == ) || (CkCode[k] == '' && OneNum[k] % == ))
  52. DISK[i][x_bits[k]][k] = '';
  53. else
  54. DISK[i][x_bits[k]][k] = '';
  55. }
  56. else //奇校验
  57. {
  58. if ((CkCode[k] == ''&&OneNum[k] % == ) || (CkCode[k] == '' && OneNum[k] % == ))
  59. DISK[i][x_bits[k]][k] = '';
  60. else
  61. DISK[i][x_bits[k]][k] = '';
  62. }
  63. }
  64. else //该行没有x数据,直接检错
  65. {
  66. if (ct == 'E' && ((CkCode[k] == ''&&OneNum[k] % == ) || (CkCode[k] == '' && OneNum[k] % == )))
  67. flag = -;
  68. if (ct == 'O' && ((CkCode[k] == ''&&OneNum[k] % == ) || (CkCode[k] == '' && OneNum[k] % == )))
  69. flag = -;
  70. }
  71. }
  72. }
  73. getchar();
  74. return flag;
  75. }

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

  1. //转换16进制输出
  2. void printValidData()
  3. {
  4. int n = ;
  5. int m;
  6. //获取每一行数据,进行输出
  7. for (int i = ; i < row; i++)
  8. {
  9. m = ;
  10. for (int j = ; j < col; j++)
  11. {
  12. if (i%col==j) continue; //跳过校验位
  13. for (int k = ; k < bits; k++)
  14. {
  15. if (DISK[i][j][k] == '')
  16. n |= 0x01;
  17. else
  18. n |= 0x00;
  19. m++;
  20. if (m == )
  21. {
  22. printf("%X", n);
  23. n = , m = ;
  24. }
  25. n <<= ;
  26. }
  27. }
  28. //获取完一行
  29. if (m > && m != )
  30. {
  31. m++;
  32. while (m != )
  33. {
  34. n |= 0x00,n <<= ;
  35. m++;
  36. }
  37. printf("%X", n);
  38. }
  39. }
  40. printf("\n");
  41. }

主函数

  1. void main()
  2. {
  3. int c = , flag;
  4. FILE* fp = freopen("data7.in", "r", stdin);
  5. freopen("data7.out", "w", stdout);
  6.  
  7. while (!feof(fp))
  8. {
  9. flag = getDiskData();
  10. if (flag == ) break;
  11. if (flag == -)
  12. printf("Disk set %d is invalid.\n",c++);
  13. else
  14. {
  15. printf("Disk set %d is valid, contends are: ",c++);
  16. printValidData();
  17. }
  18. }
  19.  
  20. freopen("CON", "r", stdin);
  21. freopen("CON", "w", stdout);
  22. }

算法习题---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. 结构型模式(一) 适配器模式(Adapter)

    一.动机(Motivation) 在软件系统中,由于应用环境的变化,常常需要将"一些现存的对象"放在新的环境中应用,但是新环境要求的接口是这些现存对象所不满足的. 如何应对这种&q ...

  2. Redis面试基本问题

    Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet.如果你是Redis中高级用户,还需要加上下面几种数据结构HyperLogLog.Ge ...

  3. ES的入门学习

    ES的入门:ES的雇员文档的设计和实现功能 ES的存放中包括:索引,类型,文档,字段 PUT /megacorp/employee/1{{ "first_name" : " ...

  4. LeetCode 364. Nested List Weight Sum II

    原题链接在这里:https://leetcode.com/problems/nested-list-weight-sum-ii/description/ 题目: Given a nested list ...

  5. ArrayList 集合的几种遍历的方法

    ArrayList 集合  也可称作动态数组(长度可变),在新建的时候是没有默认长度的,在新增数据长度小于10的时候,ArrayList 的长度会自动设置为10 //了解更多可以按住Ctrl 再点击你 ...

  6. C++中unique函数的用法总结

    个人感觉,unique是STL中很实用的函数之一,需要#include,下面来简单介绍一下它的作用. unique的作用是"去掉"容器中相邻元素的重复元素,这里去掉要加一个引号,为 ...

  7. 贴一段Matlab代码

    % reduce leading zeros with rx ind3= find(rx~=0, 1, 'first'); if (isempty(ind3)) rx= gf(0, m, f0); e ...

  8. 原创:ThreadPoolExecutor线程池深入解读(一)----原理+应用

    本文档,适合于对多线程有一定基础的开发人员.对多线程的一些基础性的解读,请参考<java并发编程>的前5章. 对于源代码的解读,本人认为可读可不读.如果你想成为一位顶级的程序员,那就培养自 ...

  9. Coupled和segregated【转载】

    转载自:http://blog.sina.com.cn/s/blog_67873f6c0100ltq6.html 问题1: 我看中文帮组里说是'分离'的意思?我绝对翻译不太好,请问有更好的翻译吗? 和 ...

  10. JavaWeb之基础(2) —— HTTP协议

    1. 粗讲什么是HTTP协议 HTTP协议的全程是Hyper Text Transfer Protocol,超文本传输协议,见名知意,这是个用来控制传输超文本的协议.下面就来简单说说什么是HTTP协议 ...