uva 509 RAID! (disk data)

From
https://blog.csdn.net/su_cicada/article/details/80085318

Exercise 4-7 RAID Technology (RAID!, ACM/ICPC World Finals 1997, UVa509)
RAID technology uses multiple disks to store data. Each copy of data is kept on more than one disk, so if one disk fails
, it can be recovered from another disk. This topic discusses one of the RAID technologies. Data is divided into
data blocks of size s (1≤s≤64) bits and stored on d (2≤d≤6) disks, as shown in Figure 4-9, every d-1 data block
has one Check the blocks so that the XOR result of every d data blocks is all 0s (even parity) or all 1s (odd parity).
write picture description here
Figure 4-9 Data storage situation
For example, d=5, s=2, even parity, data 6C7A79EDFC (binary 01101100 01111010 01111001
11101101 11111100) is saved as shown in Figure 4-10.
write picture description here
Figure 4-10 Data storage method of 6C7A79EDPC The
bold block is the check block. Enter d, s, b, the type of parity (E means even parity, O means odd parity)
and b (1≤b≤100) data blocks (where "x" means corrupted data), your The task is to restore and output the complete
data. If the checksum is wrong or too much corrupted data cannot be recovered, the disk should be reported as illegal.
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

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=833&problem=450&mosmsg=Submission+received+with+ID+21205211

Note:
(The order of the row and column blocks is as shown in the figure, one disk track is one column)
1. The check block is the one without hexadecimal operation.
2. The order of the check block is the first block of the first row. The second of the second line, when it reaches the last of a certain line, the next line will be counted as a check block from the first one.
3. Hexadecimal conversion is a hexadecimal number that requires four binary digits, so Every four bits of binary is a hexadecimal
4. The check is performed on the same bit of each block in a
row
. , There are two possibilities that the disk is unreasonable: one is that the known bit check does not match, the other is that the unknown bit has multiple bits, and its content cannot be judged

7. Regarding the input content:
the first number is the number of disk tracks, that is, the number of columns,
the second number is the number of binary bits contained in each data block, and the
third number is how many rows of data there are, which is the number of rows
8 , The segmentation of the input data stream is meaningless and needs to be arranged later.
9. The data storage is to store one track first and then store the next one, that is, it is stored vertically in the order of the columns (planted here)

Ideas:
1. Store data: use a three-dimensional array, or a two-dimensional vector vector (elements are strings or ints). The three-dimensional array I use can be imagined as each data block rising from the ground on a plane composed of rows and columns Upward 01 column
2. The whole is divided into two parts: fill in the missing bits, and convert the hexadecimal
3. Completion: first cycle the row, then cycle the bits in the block, use each bit to cycle through the column, the current value of each column The bit is XORed, and the result is the same as the parity check, that is, 0, 1. If it is different, it is wrong. If there is x, first record the subscript of x, and the final result after calculation is the value of x. If there are more than one x, it is wrong.
4. Binary to hexadecimal: It can be solved by 16-line violence, or it can be converted into decimal, and the six numbers greater than 9 are listed and output
. 5. Pay attention to the order of the three numbers at the beginning of the input.
6. You can use a function to view the stored data. data.
Gone

I used a dynamically allocated array for this code. I found it on the Internet. It's very interesting. The triple pointer in C language is really wonderful. The pointer itself is also a variable. What's special is that the value stored in it is another variable. It's just the address, that's all, no matter how many pointers

//uva 509 RAID(磁盘数据)
#include<iostream>
#include<string>
using namespace std;
/*
1 0 1
1 1 0
0 0 0
0 1 1
*/
//列个行 bca
int a,b,c; //数据块(几行),磁盘(一行几个,列),一单位数据几位

//一个显示三维表的函数,辅助,不用也可以
void show(char ***disk)
{
    for(int i=0;i<a;i++)
    {
        for(int j=0;j<b;j++)
        {
            for(int k=0;k<c;k++)
                cout<<disk[i][j][k];
            cout<<"_";
        }
        cout<<endl;
    }
    cout<<endl;
}

int repair(char ***disk,int od_ev)//od_ev直接传来0或1
{
    //应该先循环a,再循环c,后循环b
    //找到一位然后 循环一行中所有的这个位
    //cout<<a<<"  "<<b<<"  "<<c<<endl;
    for(int i=0;i<a;i++)
    {
        for(int k=0;k<c;k++)
        {
            int yihuo=0;
            int x_num=-1;
            for(int j=0;j<b;j++)
            {
//        cout<<i<<" "<<j<<"  "<<k<<endl;
//        show(disk);
                if(disk[i][j][k]=='x')
                {
                    if(x_num!=-1)
                        return 0;//disk invalid
                    x_num=j;
                }
                else
                    yihuo=yihuo^(disk[i][j][k]-'0');
            }
            if(x_num!=-1)
                disk[i][x_num][k] = yihuo^od_ev+'0';
            else if(yihuo!=od_ev)
                return -1;   //数据错误
        }
    }
    return 1;
}

char hex(string bin)//char b1,char b2,char b3,char b4)
{
    //cout<<bin<<"----"<<endl;
    int n=(bin.at(0)-'0')*2*2*2+ (bin.at(1)-'0')*2*2 + (bin[2]-'0')*2+ (bin[3]-'0');
    if(n<10) return (n+'0');
    switch(n)
    {
        case 10:return 'A';
        case 11:return 'B';
        case 12:return 'C';
        case 13:return 'D';
        case 14:return 'E';
        case 15:return 'F';
    }
//    以下是暴力解233
//    string h="0000";
//    h[0]=b1;
//    h[1]=b2;
//    h[2]=b3;
//    h[3]=b4;
//    if(h=="0000") return "0";
//    if(h=="0001") return "1";
//    if(h=="0010") return "2";
//    if(h=="0011") return "3";
//    if(h=="0100") return "4";
//    if(h=="0101") return "5";
//    if(h=="0110") return "6";
//    if(h=="0111") return "7";
//    if(h=="1000") return "8";
//    if(h=="1001") return "9";
//    if(h=="1010") return "A";
//    if(h=="1011") return "B";
//    if(h=="1100") return "C";
//    if(h=="1101") return "D";
//    if(h=="1110") return "E";
//    if(h=="1111") return "F";

}
int main()
{
    int NUM =0;
    while(cin>>b>>c>>a&&b!=0)  //注意输入的顺序
    {
        char ***disk;
        char od_ev;
        cin>>od_ev;

        disk = new char**[a]; //disk指向存着a个char**型的空间
        //char **disk[a]
        for(int i=0;i<a;i++)
            disk[i] = new char*[b];   //disk里的每个元素指向存着b个char*型空间
            //char *disk[i][b]
        for(int i=0;i<a;i++)
            for(int j=0;j<b;j++)
                disk[i][j] = new char[c];

            for(int j=0;j<b;j++)
        for(int i=0;i<a;i++)
                for(int k=0;k<c;k++)
                    cin>>disk[i][j][k];

        NUM++;
        cout<<"Disk set "<<NUM<<" is ";

        int retu = repair(disk,od_ev=='E'?0:1);
        if(retu!=1)
        {
            cout<<"invalid."<<endl;
            continue;   //进行下一次大循环
        }
        //cout<<retu<<endl;

        //show(disk);


        string result;
        string bin;     //要转十六进制的四位二进制
        int num=0;      //间隔是4,代表四位二进制
        int sum=a*b*c-a*c;  //一共要过的字符量,除去校验位
        for(int i=0;i<a;i++)
            for(int j=0;j<b;j++)
            {
                if((i+1)%b==(j+1)%b)  //校验码
                {
                    //sum-=c;  //将查过的这c个也要记录
                    continue;
                }
                for(int k=0;k<c;k++)
                {
//                    cout<<"disk"<<i<<" "<<j<<" "<<k<<" "<<(disk[i][j][k])<<endl;;
                    bin.append(1,disk[i][j][k]);   //这里的1代表加入1个处于第二个元素的字符,这里没处理好。
                    num++;
//                    cout<<bin<<"__"<<sum<<" "<<num<<endl;
                    if(num%4==0)
                    {
                        result.append(1,hex(bin));
                        bin.erase();
                    }
                    else if(sum%4!=0&&sum==num)
                        result.append(1,hex(bin+"0000"));
                }
            }

        cout<<"valid, contents are: ";
        cout<<result<<endl;

    }//while

    return 0;
}
//AC at 2018/4/25

(Off-topic: This accidentally took another night. After passing the sample, I did it once the next day. Hahaha, I can only write programs to find the meaning of confidence. I write code every day. I don’t have much time. I feel like it’s better to write programs, and I can get a little sense of accomplishment every day. It’s really troublesome every day, and I may be limited to that)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324855591&siteId=291194637