这个问题有点意思, 难度适中, 是类似加密与解密的算法.
李雷和韩梅梅坐前后排,上课想说话怕被老师发现,所以改为传小纸条。为了不被老师发现他们纸条上说的是啥,他们约定了如下方法传递信息:
将26个英文字母(全为大写),外加空格,一共27个字符分成3组,每组9个。也就是ABCDEFGHI 是第一组,JKLMNOPQR 是第二组,STUVWXYZ* 是第三组(此处用 * 代表空格)。
然后根据传递纸条那天的日期,改变字母的位置。
先根据月份数m,以整个分组为单位进行循环左移,移动(m-1)次。
然后根据日期数d,对每个分组内的字符进行循环左移,移动(d-1)次。
.
以3月8日为例,首先移动分组,3月需要循环左移2次,变成:
STUVWXYZ* ,ABCDEFGHI,JKLMNOPQR
然后每组内的字符,8日的话需要循环左移7次,最终的编码为:
Z*STUVWXY,HIABCDEFG,QRJKLMNOP
对于要传递信息中的每个字符,用组号和组内序号两个数字来表示。
如果在3月8日传递信息“HAPPY”,那么H位于第2组的第1个,A位于第2组第3个,P位于第3组第9个,Y位于第1组第9个,所以纸条上会写成:
21 23 39 39 19
现在给定日期和需要传递的信息,请输出应该写在纸条上的编码。
每个输入包含两行。第一行是用空格分隔的两个数字,第一个数字是月份,第二个数字是日子。输入保证是一个合法的日期。
第二行为需要编码的信息字符串,仅由A~Z和空格组成,长度不超过1024个字符。
对每个输入,打印对应的编码,数字之间用空格分隔,每个输出占一行。
.
输入示例1:
1 1
HI
输出示例1:
18 19
.
输入示例2:
3 8
HAPPY
输出示例2:
21 23 39 39 19
.
输入示例3:
2 14
I LOVE YOU
输出示例3:
35 25 18 12 29 31 25 23 12 28
此处李和韩的交流通过一种自定义的加密解密方法实现聊天内容的相对安全. 主要加密方式是通过当前日期的Month 和Day, 对聊天内容进行左移算法加密. 聊天内容使用"密码本": 第一组数据ABCDEFGHI,第二组数据JKLMNOPQR,第三组数据STUVWXYZ来代替. 其中 指代空格. 根据Month 左移"密码本"三个分组, 根据Day 左移分组的组内元素.
重点加密方法, 先根据月份数m, 以整个分组为单位进行循环左移, 移动(m-1)次. 然后根据日期数d, 对每个分组内的字符进行循环左移, 移动(d-1)次.
(传纸条都纯英文交流, SIX)
分析题意后封装了几个方法, main 是Java 类的主函数. 详细说明已写在代码注释中.
void main(String[] args)
main方法
程序主函数, 主要动作包括读取用户的键入数据, 调用加密方法, 输出加密内容.
List dataEncryption(int month, int day, String information)
加密聊天内容方法
传参是月份, 本月的第几天, 聊天内容.
void movebitList(int moveByMonth)
集合数组左移方法
传参是月份, 根据月份推算集合内元素左移次数, 进行元素的左移.
void movebit(String array[], int times)
数组左移方法
这里会用到左移算法. 对一个数组内的元素进行左移, 每次左移一位. 参数arrays[] 是被移动元素的数组, times 是数组元素左移的次数.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* @Description : 课堂交流加密解密问题
* @Author: niaonao
* @Date: 2018/11/18 23:20
*/
public class EncryptDecryptCommunicate{
//加密规则
private static String[] strsFirst = {"A", "B", "C", "D", "E", "F", "G", "H", "I"};
private static String[] strsSecond = {"J", "K", "L", "M", "N", "O", "P", "Q", "R"};
private static String[] strsThird = {"S", "T", "U", "V", "W", "X", "Y", "Z", "*"};
private static List<String[]> strsList = new ArrayList<String[]>() {
{
add(strsFirst);
add(strsSecond);
add(strsThird);
}
};
public static void main(String[] args) {
//根据输入的日期(月/日)
Scanner sc = new Scanner(System.in);
int month = sc.nextInt();
int day = sc.nextInt();
Scanner cin = new Scanner(System.in);
//全大写
String information = cin.nextLine();
//经过加密得到加密后数据
List<String> data = dataEncryption(month, day, information);
//nums[] 35 25 18 12 29 31 25 23 12 28
for (String nums : data) {
System.out.print(nums + " ");
}
}
/**
* 加密对话内容
*
* @param month
* @param day
* @param information
* @return
*/
private static List<String> dataEncryption(int month, int day, String information) {
//整个分组左移
int moveByMonth = month - 1;
movebitList(moveByMonth);
//每个分组内部左移
int moveByDay = day - 1;
movebit(strsList.get(0), moveByDay);
movebit(strsList.get(1), moveByDay);
movebit(strsList.get(2), moveByDay);
//对信息的每个字符进行加密。
//获取字符串每个字符,
//比对当前字符在strsList的第几组的第几个位置,比如2,1即该字符加密为21
//封装加密后数据
List<String> data = new ArrayList<String>();
//对数据加密
for (int i = 0; i < information.length(); i++) {
//在整组中位置
//在分组中位置
int listNum = 0;
int arrayNum = 0;
char character = information.charAt(i);
//空格处理
if (' ' == character)
character = '*';
//字符是否匹配到
boolean alreadyFind = false;
for (int j = 0; j < strsList.get(0).length; j++) {
String charInList = strsList.get(0)[j];
String charStr = character + "";
if (charStr.equals(charInList)) {
listNum = 1;
arrayNum = j + 1;
alreadyFind = true;
}
}
if (!alreadyFind) {
for (int j = 0; j < strsList.get(1).length; j++) {
String charInList = strsList.get(1)[j];
String charStr = character + "";
if (charStr.equals(charInList)) {
listNum = 2;
arrayNum = j + 1;
alreadyFind = true;
}
}
}
if (!alreadyFind) {
for (int j = 0; j < strsList.get(2).length; j++) {
String charInList = strsList.get(2)[j];
String charStr = character + "";
if (charStr.equals(charInList)) {
listNum = 3;
arrayNum = j + 1;
alreadyFind = true;
}
}
}
String position = listNum + "" + arrayNum;
data.add(position);
}
return data;
}
/**
* 集合整组左移方法
*
* @param moveByMonth
*/
private static void movebitList(int moveByMonth) {
if (moveByMonth % 3 == 1) {
//左移一位
String[] strsTemp = strsList.get(0);
strsList.set(0, strsList.get(1));
strsList.set(1, strsList.get(2));
strsList.set(2, strsTemp);
} else if (moveByMonth % 3 == 2) {
//左移两位
String[] strsTemp = strsList.get(1);
strsList.set(0, strsList.get(2));
strsList.set(1, strsList.get(0));
strsList.set(2, strsTemp);
}
}
/**
* 左移算法
*
* @param array 数组
* @param times 移动次数
*/
private static void movebit(String array[], int times) {
while (times > 0) {
times--;
String temp = array[0];
for (int i = 0; i < array.length - 1; i++) {
array[i] = array[i + 1];
}
array[array.length - 1] = temp;
}
}
}