2013-05-05 09:00:37Morris

[UVA][字串處理] 726 - Decode


  Decode 

Any one-to-one mapping f of the alphabet to itself can be used to encode text by replacing each occurence of letter c with f(c).



Example: One such mapping could be the mapping of a letter to three positionsbeyond the letter
		in the alphabet:  For example,  a->d, b->e, c->f, d->g, ... etc. 
 
		 natural language: The car is blue. 

encoded message: Wkh fdu lv eoxh.

The mapping that defines the encoding is one-to-one. That is, two different letters do not map to the same letter of the alphabet (a->x and t->x is impossible).

Input and Output 

The input file contains two messages separated by a blank line. We will refer to them as `KNOWN' and `ENCODED' messages. This file contains an encoded message.


You are to write a program that decodes the message in the file according to the following guidelines.

1.
The input message KNOWN contains a natural language text that is written by the same person that wrote the encoded message in ENCODED. It is to be assumed that the person uses letters of the alphabet with the same relative frequency from document to document. Read KNOWN and count the number of times each letter of the alphabet occurs. Order the letters of the alphabet in such a way that the first in the ordering is the most frequently used letter in KNOWN and the last in the list is the least frequently used letter in KNOWN. Break all ties for letters that occur at the same frequency alphabetically. That is, if both p and w appeared in KNOWN exactly 12 times each, then p would precede w in the ordered list.

2.
Read ENCODED and count the number of times each encoded letter of the alphabet occurs. Order the letters in such a way that the first in the ordering is the most frequently used letter in ENCODED and the last in the list is the least frequently used letter in ENCODED. Again, break all ties alphabetically.

3.
The process for counting the frequencies with which letters occur is to be case insensitive. That is, the appearance of the letter W followed by w would account for two occurences of that letter.

4.
The counting process is only to count letters of the alphabet, not other characters.

5.
The program is to assume that the most frequently used letter in KNOWN maps to the most frequently used letter in ENCODED; the second most frequently used letter in KNOWN maps to the second most frequently used letter in ENCODED; ... etc.

6.
Your program is to use knowledge of the mapping described in specification 5 to decode the message and put the decoded message in the output file.

7.
Even though the counting process was to be case insensitive, the deconding process is to be case sensitive. That is, encoded capital letters are to be decoded into capital letters, and encoded lower case letters are to be decoded into lower case letters.

8.
All non-alphabetic characters found in ENCODED are to pass unchanged and appear in the same relative position in the output file as in the input message ENCODED. For example, this message may contain blank lines which must appear also in the output file.

Sample Input 

The car is blue.

Wkh fdu lv eoxh.

Sample Output 

The car is blue.



Miguel Revilla
2000-08-31

根據頻率由高至低,相同則按照字典順序。
兩者內容排序後,可以得到映射。
接著將加密文檔解密。
原文之間不會有空白行,但加密文可能會有空白行。

得到很多 RE,因為輸入很大量,而且很多行。

#include <stdio.h>
#include <algorithm>
#include <iostream>
using namespace std;
int KNOWN[26] = {}, ENCODED[26] = {};
int A[26], B[26];
bool cmp1(int a, int b) {
    if(KNOWN[a] != KNOWN[b])
        return KNOWN[a] > KNOWN[b];
    return a < b;
}
bool cmp2(int a, int b) {
    if(ENCODED[a] != ENCODED[b])
        return ENCODED[a] > ENCODED[b];
    return a < b;
}
string msg[1048576];
int main() {
    int i, j, k, row = 0;
    while(getline(cin, msg[0]) && msg[0][0]) {
        for(i = 0; i < msg[0].length(); i++) {
            if(msg[0][i] >= 'A' && msg[0][i] <= 'Z')
                KNOWN[msg[0][i]-'A']++;
            if(msg[0][i] >= 'a' && msg[0][i] <= 'z')
                KNOWN[msg[0][i]-'a']++;
        }
    }
    while(getline(cin, msg[row])) {
        for(i = 0; i < msg[row].length(); i++) {
            if(msg[row][i] >= 'A' && msg[row][i] <= 'Z')
                ENCODED[msg[row][i]-'A']++;
            if(msg[row][i] >= 'a' && msg[row][i] <= 'z')
                ENCODED[msg[row][i]-'a']++;
        }
        row++;
    }
    for(i = 0; i < 26; i++)
        A[i] = B[i] = i;
    sort(A, A+26, cmp1);
    sort(B, B+26, cmp2);
    int C[26];
    for(i = 0; i < 26; i++)
        C[B[i]] = A[i];
    for(i = 0; i < row; i++) {
        for(j = 0; j < msg[i].length(); j++) {
            if(msg[i][j] >= 'A' && msg[i][j] <= 'Z')
                putchar(C[msg[i][j]-'A']+'A');
            else if(msg[i][j] >= 'a' && msg[i][j] <= 'z')
                putchar(C[msg[i][j]-'a']+'a');
            else
                putchar(msg[i][j]);
        }
        puts("");
    }
    return 0;
}