【2009】设计一个简单的编码、解码程序

Time Limit: 3 second
Memory Limit: 2 MB

假定涉及的是英文句子,且仅由英文大写字母、逗号、句点和空格符组成,例如:ON A CLEAR DAY,YOU CAN SEE FOREVER
编码代码如下:
先输入一个正整数n(1<=n<=26),它与某个英文大写字母相对应,比如n=9对应字母I。这个字母确定了对原句中英文字母的转换,如原码是ABCDEFG,转换码是IJKLMNO,其他字符则不变。因此原句转换成:WV I K TMIZ LIG,GWC KIV AMM NMZMDMZ,为了使得较难破译,特将上述转换后的信息在自左向右两两字符交换,若最后剩下单个字符则不换。然后,将一开始表示转换关系的字母置于前面,便产生了最后的编码:IVWI K MTZIL GIG,CWK VIA MMN ZWDMZM。

Input

输入一串英文句子(由英文大写字母、逗号、句点和空格符组成)和整数n(1<=n<=26):
再输入一行经过编码处理的最后编码
第一行输入英文句子。
第二行输入整数n的值。
第三行输入经过编码处理后的编码

Output

输出编码结果和译码结果:
第一行输出最后的编码。
第二行输出译码结果。

Sample Input

ON A CLEAR DAY,YOU CAN SEE FOREVER
9
IFAJKAHUHZ ZJL?

Sample Output

IVWI K MTZIL GIG,CWK VIA MMN ZWDMZM
SXCBZSZM RBR?D

【题解】

用c++的加法,int 和 char的互换,可以很快解决字母的转化.大于'Z'的时候再重新转化成'A',一步一步转化.可以弄一个过程,1代表忘后转化,而2代表往前转化字母。、

换位只要for到偶数位,然后和前面一个换位就好。奇数位就换,可能会有剩下一个的情况。会出错。

string类可以加减法,key加上去很简单。取出来用substr函数(1,2),表示从1开始截取两位string类

会有空格,cin函数不能读取空格,虽然在一行,但后面一段会被忽略。要用cin.getline(char类数组,char数组的大小),先把输入的东西整行输入char数组,之后

string s1 = string(char类数组),强制转化成string类.

【代码】

#include <cstdio>
#include <iostream>
#include <string>

using namespace std;

string s1,s2;
int n,ls1,ls2;

void input_data()
{
	char ts1[300]; //先定义一个char 数组,用来存储整行输入的字符 
    cin.getline(ts1,300);
    s1 = string(ts1); //转换成string类 
    cin >> n;
    cin.get();//这里要用一个get函数,不然读取不了第3行。应该是getline函数必须要用到的。 
    char ts2[300];
    cin.getline(ts2,300);
    s2 = string(ts2);
    ls1 = s1.size(); //string.size()表示字符串的长度 
    ls2 = s2.size();
}

void chan_ge(char &z,int k,int d) //change 函数(z表示要变的单个字符,k表示key秘钥,d表示改变的方向) 
{
    if (d == 0) //正向改变 
	    {
    	    z+= (k-1);
    	    if (z > 'Z') 
			    z = 'A' + z - 'Z'-1; //超过Z的处理方法 
        }	//反向改变 
            else 
                {
                    z-= (k-1);
                    if (z < 'A') //小于A的处理方法 
                        z = 'Z'-('A'-z-1);
                }
    	
}

void ex_change( char &a,char &b) //交换位置 注意要加& 
{
	char t =a;
	a = b;
	b = t;	
}

void get_ans()
{
    for (int i = 0 ; i < ls1;i++)  //字符串是从0开始计数 
    	if ((s1[i] <= 'Z') && (s1[i] >= 'A'))  //如果这个字符是字母 
		    chan_ge(s1[i],n,0); //转换 
    for (int i = 0 ; i < ls1;i++) //是奇数(字符串是从0) 
    	if ( (i % 2) == 1) 
    		ex_change(s1[i],s1[i-1]);
    char key = 'A' + n -1;  
    s1 = key + s1; //把秘钥加到字符串的开头 
    
    n = s2[0] - 'A' +1; //取出秘钥 
    s2 = s2.substr(1,ls2-1); //截取开头的秘钥 
    ls2--;
    for (int i = 0;i < ls2;i++) //同样交换 
        if ( (i % 2) == 1) 
    	    ex_change(s2[i],s2[i-1]);
    for (int i = 0;i < ls2;i++)
    	if ((s2[i] <= 'Z') && (s2[i] >= 'A')) //判断为字母后反向转换。 
    	    chan_ge(s2[i],n,1); 
}

void output_ans()
{
	cout << s1 << endl;
	cout << s2;	
}

int main()
{
	//freopen("E:\rush.txt","r",stdin);
	input_data();
	get_ans();
	output_ans();
	return 0;	
}


 

原文地址:https://www.cnblogs.com/AWCXV/p/7632497.html