JXUFE紫书第四章习题4-7

原题描述:

RAID (Redundant Array of Inexpensive Disks) is a technique which uses multiple disks to store data.By storing the data on more 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 recover the original data providedthat the remaining disks do not have corresponding problems.One approach to RAID breaks data into blocks and stores these blocks on all but one of the disks.The remaining disk is used to store the parity information for the data blocks. This scheme uses verticalparity in which bits in a given position in data blocks are exclusive ORed to form the correspondingparity bit. The parity block moves between the disks, starting at the first disk, and moving to the nextone in order. For instance, if there were five disks and 28 data blocks were stored on them, they wouldbe arranged as follows:Disk 1 Disk 2 Disk 3 Disk 4 Disk 5Parity for 1-4 Data block 1 Data block 2 Data block 3 Data block 4Data block 5 Parity for 5-8 Data block 6 Data block 7 Data block 8Data block 9 Data block 10 Parity for 9-12 Data block 11 Data block 12Data block 13 Data block 14 Data block 15 Parity for 13-16 Data block 16Data block 17 Data block 18 Data block 19 Data block 20 Parity for 17-20Parity for 21-24 Data block 21 Data block 22 Data block 23 Data block 24Data block 25 Parity for 25-28 Data block 26 Data block 27 Data block 28With this arrangement of disks, a block size of two bits and even parity, the hexadecimal sampledata 6C7A79EDFC (01101100 01111010 01111001 11101101 11111100 in binary) would be stored as:Disk 1 Disk 2 Disk 3 Disk 4 Disk 500 01 10 11 0001 10 11 10 1001 11 01 10 0111 10 11 11 0111 11 11 00 11If a block becomes unavailable, its information can still be retrieved using the information on theother disks. For example, if the first bit of the first block of disk 3 becomes unavailable, it can bereconstructed using the corresponding parity and data bits from the other four disks. We know thatour sample system uses even parity:0 ⊕ 0⊕? ⊕ 1 ⊕ 0 = 0So the missing bit must be 1.An arrangement of disks is invalid if a parity error is detected, or if any data block cannot bereconstructed because two or more disks are unavailable for that block.Write a program to report errors and recover information from RAID disks.InputThe input consists of several disk sets.Each disk set has 3 parts. The first part of the disk set contains three integers on one line: the firstinteger d, 2 ≤ d ≤ 6, is the number of disks, the second integer s, 1 ≤ s ≤ 64, is the size of each blockin bits, and the third integer b, 1 ≤ b ≤ 100, is the total number of data and parity blocks on eachdisk. The second part of the disk set is 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 holdings × b characters representing the bits on the disk, with the most significant bits first. Each bit will bespecified as ‘0’ or ‘1’ if it holds valid data, or ‘x’ if that bit is unavailable. The end of input will be adisk set with d = 0. There will be no other data for this set which should not be processed.OutputFor each disk set in the input, 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. If necessary, add extra ‘0’ bits atthe end of the recovered data so the number of bits is always a multiple of 4. All output shall beappropriately labeled.

Sample Input

5 2 5

E

0001011111

0110111011

1011011111

1110101100

0010010111

3 2 5

E

0001111111

0111111011

xx11011111

3 5 1

O

11111

11xxxx

11110

Sample Output

Disk set 1 is valid, contents are: 6C7A79EDFC

Disk set 2 is invalid.

Disk set 3 is valid, contents are: FFC

解题思路:1.每一竖排上,如果有奇数个1,则为奇校验,否则为偶校验.

                 2.每一竖排最多可以损坏一个数据,否则无法恢复数据。  

#include <stdio.h>
#include <string.h>


int d,s,b;//2<=d<=6  1<=s<=64 1<=b<=100
char parity;
char disk[10][10000];//磁盘数据
char info[100000];
char content[100000]; 
int infocount;
int contentcount;
int main(){
    int i,j,k; 
    char str[10];
    int be;//非校验位
    int bcount; 
    int kase=0;
    int onecount;//数1的个数
    int P; //even odd parity
    int Q;//even odd error
    int need;
    int tmpi;
    char tmpc;
    int eox;
    while(scanf("%d",&d)&&d){//d=0退出 
        scanf("%d%d",&s,&b);
        scanf("%s",str);
        parity=str[0];//'E' 'O'
        for(i=0;i<d;i++){//硬盘数据读取 
            scanf("%s",disk[i]);
        }
        kase++;
               
        //检查统一行上,同一位上是否有两个或以上数据出错
        be=0;
        for(j=0;j<b;j++){//s个位,取出一同位
            for(k=0;k<s;k++){
                bcount=0;
                for(i=0;i<d;i++){
                    if(disk[i][j*s+k]=='x'){
                        bcount++;
                        if(bcount>=2){
                            be=1;
                            break;
                        }
                    }
                }
                if(be==1)
                    break;
            }
            if(be==1)
                break;
        }
        if(be==1){
            printf("Disk set %d is invalid.\n",kase);
            continue;
        }
        
        //奇偶校验是否正确,遇到'x',跳过该位 
        if(parity=='E')//偶数个1 
            P=0;
        else//奇数个1 
            P=1;
        Q=0;
        for(j=0;j<b;j++){
            for(k=0;k<s;k++){
                onecount=0;
                eox=0;
                for(i=0;i<d;i++){
                    if(disk[i][j*s+k]=='1'){
                        onecount++;
                    }else if(disk[i][j*s+k]=='x'){
                        eox=1;
                    }
                }
                if(eox!=1&&onecount%2!=P){//校验失败
                    Q=1;
                    break; 
                }
            }
            if(Q==1)
                break;
        }
        if(Q==1){
            printf("Disk set %d is invalid.\n",kase);
            continue;
        } 
        
        //硬盘数据有效,数据进行处理 
        //修补数据
        for(j=0;j<b;j++){
            for(k=0;k<s;k++){
                onecount=0;
                need=0;
                for(i=0;i<d;i++){
                    if(disk[i][j*s+k]=='1'){
                        onecount++;
                    }
                    if(disk[i][j*s+k]=='x'){
                        need=1;
                        tmpi=i;
                    }
                } 
                if(need){//修补数据
                    if(onecount%2==P)
                        disk[tmpi][j*s+k]='0';
                    else
                        disk[tmpi][j*s+k]='1';
                }
            }
        } 
        
        
        // 数据内容读取
        infocount=0;
        for(j=0;j<b;j++){
            for(i=0;i<d;i++){
                for(k=0;k<s;k++){
                    if(j%d!=i){
                        info[infocount]=disk[i][j*s+k];
                        infocount++;
                    }
                }
            }
        } 
        if(infocount%4!=0){
            k=4-infocount%4;
            for(i=0;i<k;i++){
                info[infocount]='0';
                infocount++;
            }
        }
        info[infocount]='\0';//字符串结束标志
        //二进制转十六进制
        contentcount=0;
        for(i=0;i<infocount;i++){
            if(i%4==0){
                //十六进制开始 
                k=0;
                k+=(info[i]-'0')*2*2*2;
            }else if(i%4==1){
                k+=(info[i]-'0')*2*2;
            }else if(i%4==2){
                k+=(info[i]-'0')*2;
            }else if(i%4==3){
                k+=info[i]-'0';
                //十六进制结束 
                switch(k){
                    case 10:
                        tmpc='A';
                        break;
                    case 11:
                        tmpc='B';
                        break;
                    case 12:
                        tmpc='C';
                        break;
                    case 13:
                        tmpc='D';
                        break;
                    case 14:
                        tmpc='E';
                        break;
                    case 15:
                        tmpc='F';
                        break;
                    default:
                        tmpc=k+'0';
                }
                content[contentcount]=tmpc;
                contentcount++;
            }
        } 
        content[contentcount]='\0';//字符串结束
        contentcount++;
        printf("Disk set %d is valid, contents are: %s\n",kase,content); 
    }
    return  0;
}

                  


猜你喜欢

转载自blog.csdn.net/jxufe_acmer/article/details/80328881
今日推荐