509 - RAID!
来源:互联网 发布:怎么跟网络管理员联系 编辑:程序博客网 时间:2024/06/07 00:47
RAID (Redundant Array of Inexpensive Disks)is a technique which uses multiple disks to store data. By storing the data onmore than one disk, RAID is more fault tolerant than storing data on a singledisk. If there is a problem with one of the disks, the system can still recoverthe original data provided that the remaining disks do not have correspondingproblems.
One approach to RAID breaks data into blocks and stores these blocks on all butone of the disks. The remaining disk is used to store the parity informationfor the data blocks. This scheme uses vertical parity in whichbits in a given position in data blocks are exclusive ORed to form thecorresponding parity bit. The parity block moves between the disks, starting atthe first disk, and moving to the next one in order. For instance, if therewere five disks and 28 data blocks were stored on them, they would be arrangedas follows:
Disk 1
Disk 2
Disk 3
Disk 4
Disk 5
Parity for 1-4
Data block 1
Data block 2
Data block 3
Data block 4
Data block 5
Parity for 5-8
Data block 6
Data block 7
Data block 8
Data block 9
Data block 10
Parity for 9-12
Data block 11
Data block 12
Data block 13
Data block 14
Data block 15
Parity for 13-16
Data block 16
Data block 17
Data block 18
Data block 19
Data block 20
Parity for 17-20
Parity for 21-24
Data block 21
Data block 22
Data block 23
Data block 24
Data block 25
Parity for 25-28
Data block 26
Data block 27
Data block 28
With this arrangement of disks, a block size of two bits and even parity,the hexadecimal sample data 6C7A79EDFC (01101100 01111010 01111001 1110110111111100 in binary) would be stored as:
Disk 1
Disk 2
Disk 3
Disk 4
Disk 5
00
01
10
11
00
01
10
11
10
10
01
11
01
10
01
11
10
11
11
01
11
11
11
00
11
If a block becomes unavailable, its information can still be retrieved usingthe information on the other disks. For example, if the first bit of the firstblock of disk 3 becomes unavailable, it can be reconstructed using thecorresponding parity and data bits from the other four disks. We know that oursample system uses even parity:
So the missing bit must be 1.
An arrangement of disks is invalid if a parity error is detected, or if anydata block cannot be reconstructed because two or more disks are unavailablefor that block.
Write a program to report errors and recover information from RAID disks.
Input
The input consists ofseveral disk sets.
Each disk set has 3 parts. The first part of the disk set contains threeintegers on one line: the first integer d, , is the number ofdisks, the second integer s, , is the size ofeach block in bits, and the third integer b, , is the totalnumber of data and parity blocks on each disk. The second part of the disk setis a single letter on a line, either ``E'' signifying even parity or ``O''signifying odd parity. The third part of the disk set contains d lines,one for each disk, each holding charactersrepresenting the bits on the disk, with the most significant bits first. Eachbit will be specified as ``0'' or ``1'' if it holds valid data, or ``x'' ifthat bit is unavailable. The end of input will be a disk set with d =0. There will be no other data for this set which should not be processed.
Output
For each disk set in theinput, display the number of the set and whether the set is valid or invalid.If the set is valid, display the recovered data bits in hexadecimal. Ifnecessary, add extra ``0'' bits at the end of the recovered data so the numberof bits is always a multiple of 4. All output shall be appropriately labeled.
Sample Input
5 2 5
E
0001011111
0110111011
1011011111
1110101100
0010010111
3 2 5
E
0001111111
0111111011
xx11011111
3 5 1
O
11111
11xxx
x1111
0
Sample Output
Disk set 1 is valid, contents are:6C7A79EDFC
Disk set 2 is invalid.
Disk set 3 is valid, contents are: FFC
错误但是没找出错误的代码:
#include<iostream>
#include<cstring>
#include<iomanip>
using namespacestd;
struct RAID
{
int n=0;
int data[6*64*100+100]= {0};
bool operate(int d,int s,int b)
{
int parity=0;
char ch;
char content[7][6*64*100+100];
cin>>ch;
if(ch=='O')
{
parity=1;
}
for(int i=0; i<d; i++)
{
for(int j=0; j<s*b; j++)
{
cin>>content[i][j];
}
}
int xnum[6410]= {0};
int exor[6410]= {0};
for(int i=0; i<d; i++)
{
for(int j=0; j<s*b; j++)
{
if(content[i][j]=='x')
{
xnum[j]++;
}
else
{
exor[j]=exor[j]^(content[i][j]-'0');
}
}
}
for(int j=0; j<s*b; j++)
{
if(xnum[j]>1)
{
return false;
}
if(xnum[j]==0&&exor[j]!=parity)
{
return false;
}
for(int i=0; i<d; i++)
{
if(content[i][j]=='x')
{
content[i][j]=(exor[j]^parity+'0');
}
}
}
for(int j=0; j<s*b; j=j+s)
{
for(int i=0; i<d; i++)
{
if(i==(j/s)%d)
{
continue;
}
for(int k=0; k<s; k++)
{
data[n++]=(content[i][j+k]-'0');
}
}
}
while(n%4!=0)
{
data[n++]=0;
}
return true;
}
void print()
{
int result=0;
for(int i=0; i<n; i=i+4)
{
result=data[i]*8+data[i+1]*4+data[i+2]*2+data[i+3]*1;
cout<<setiosflags(ios::uppercase)<<hex<<result;
}
cout<<endl;
}
};
int main()
{
int time=1;
int d,s,b;
while(cin>>d&&d!=0)
{
cin>>s>>b;
RAID A;
memset(&A,0,sizeof(A));
if(A.operate(d,s,b))
{
cout<<"Disk set"<<time<<" is valid, contents are: ";
A.print();
time++;
}
else
{
cout<<"Disk set"<<time<<" is invalid.\n";
time++;
}
}
return 0;
}
参考代码及思路:
/*
构造了一个RAID类,用一个bool类型的大数组data存储0、1正文信息
整数n代表存了多少位。然后关键是Set成员函数的实现。
Set函数尝试将数据读入与恢复,并存储在data中,
如果失败则返回0,否则返回1。
Set函数的算法和步骤是本题的核心:
它先统计每列的'x'个数,已有的01也先做异或运算。
然后做列检验,如果该列没有'x',则异或结果错误的return 0;
如果该列有一个'x',直接对其进行恢复;
如果有多个'x'的,肯定有正文信息损坏且无法恢复,故也return 0。
step 2若能顺利执行,进入该步,则此时str中一定不存在'x'。
用技巧来依次读取正文即可。*/
#include<cstdio>
#include<iostream>
using namespacestd;
struct RAID
{
int n;
bool data[64*100*6+10];
int Set(int d, int s, int b)
{
bool parity = 0;
char str[7][6410], str1[10];
// 读入数据
scanf("%s", str1);
if (str1[0]=='O')
{
parity = 1;
}
for (int i = 0; i < d; i++)
{
scanf("%s", str[i]);
}
// 统计每列有多少个x, 并统计已有01的异或值
int cnt[6410] = {}, i, j;
bool check[6410] = {};
for (i = 0; i < d; i++)
{
for (j = 0; j < s*b; j++)
{
if (str[i][j]=='x')
{
cnt[j]++;
}
else
{
check[j] ^=(str[i][j]-'0');
}
}
}
for (j = 0; j < s*b; j++) // 每列校验
{
if (cnt[j] > 1)
{
return 0;
}
if (cnt[j] == 0 && check[j]!= parity)
{
return 0;
}
// 否则只有一个x,直接恢复
for (i = 0; i < d; i++)
{
if (str[i][j]=='x')
{
str[i][j] =(parity^check[j]) + '0';
break;
}
}
}
// 生成数据data,遇到'x'时return 0
for (n = j = 0; j < s*b; j += s)
{
for (i = 0; i < d; i++)
{
if (i == (j/s)%d)
{
continue;
}// 注意此处技巧,巧妙的跳过校验码
for (int k = 0; k < s; k++)
{
data[n++] =str[i][j+k]-'0';
}
}
while (n%4 != 0)
{
data[n++] = 0;
}
return 1;
}
void out()
{
for (int i = 0; i < n; i += 4)
{
printf("%X",data[i]*8 + data[i+1]*4 + data[i+2]*2 + data[i+3]);
}
putchar('\n');
}
}
};
int main()
{
int d, s, b, kase = 0;
RAID A;
while (cin >> d >> s >> b)
{
if (A.Set(d, s, b))
{
printf("Disk set %d is valid,contents are: ", ++kase);
A.out();
}
else
{
printf("Disk set %d isinvalid.\n", ++kase);
}
}
return 0;
}
- 509 - RAID!
- 509 - RAID!
- uva 509 RAID!
- RAID
- RAID
- RAID
- raid
- RAID
- RAID
- RAID
- RAID
- RAID
- RAID
- raid
- RAID
- RAID
- RAID
- raid
- 201 - Squares
- 220 - Othello
- TypeScript函数
- 253 - Cube painting
- 508 - Morse Mismatches
- 509 - RAID!
- 815 - Flooded!
- 1589 - Xiangqi
- POJ 2342 Anniversary Party ( 树形DP )
- 1590 - IP Networks
- 1591 - Data Mining
- 12108 - Extraordinarily Tired Students
- 101 - The Blocks Problem
- 136 - Ugly Numbers