有一种常见但不安全的加密文本的方法, 是将字母表中的某个字母固定地取代另一个字母.
为了保证加密是可逆的, 没有两个字母会被同一个字母取代.
你的任务是要解密几行文本. 这几行文本在被加密的时候可能每一行都使用了不同的取代方案, 而且所有的单词都来自一个已知的词典.
输入:
输入文件包含多行. 第一行是一个整数n, 表示词典中单词的数量.
第二行开始是n个单词, 每行一个单词.
解密后的明文中的所有单词都是由这些单词组成的.
在单词之后, 是若干行密文. 每一行都是按上述方式加密的.
词典的大小小于1000. 单词不超过16个字母.
加密前后的字母都只有小写. 每一行不超过80字母.
输出:
解密每一行密文, 并打印明文. 如果有多种可能的明文, 输出任何一个即可.
如果没有可能的明文, 用星号来取代每一个字母.
测试用例1:
输入:
5
the
big
bang
theory
rock
xej mck mfok xejpwz wpdu
fff jjj pppp dddddd
输出:
the big bang theory rock
*** *** **** ******
测试用例2:
输入:
23
already
diplomacy
senate
house
agreed
hardening
further
representatives
delay
to
passed
has
iran
but
chance
succeed
a
sanctions
of
bill
allow
action
the
rko kzxbo zt sonsobohrvrqaob kvb vpsovud nvbbou v wqpp kvsuohqhi qsvh bvhgrqzhb wxr rko bohvro visoou rz uopvd txsrkos vgrqzh rz vppzy uqnpzcvgd v gkvhgo rz bxggoou
输出:
the house of representatives has already passed a bill hardening iran sanctions but the senate agreed to delay further action to allow diplomacy a chance to succeed
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class Try {
public static void main(String[] args) {
List mi=new ArrayList();//用来保存密文的链表
List usemi=new ArrayList();//已映射的密文
List usedic=new ArrayList();//已映射的单词
Map map=new HashMap();//单词密文的映射关系
Map mapp=new HashMap();
Scanner in = new Scanner(System.in);
int num=0;
boolean b=false;
boolean intsign=false;
System.out.println("输入单词的个数:");
while(!intsign){
String test=in.nextLine();
if(test.matches("[0-9]*")){
num=Integer.parseInt(test);
intsign=true;
}else{
System.out.println("请输入正确的数字");
}
}
String[] dic=new String[num];
System.out.println("输入单词:");
for(int i=0;i<num;i++){
dic[i]=in.next();
}
System.out.println("输入密文:exit表示结束");
in.nextLine();
while(true){//将密文保存到链表中
String temp=in.nextLine();
// System.out.println(temp);
if(temp.equals("exit")){
break;
}else{
mi.add(temp);
}
}
System.out.println("解密开始~~~");
int misign=0;//密文位置的记录
int dicsign=0;//单词位置的记录
int sign=0;//匹配数量的记录
int mm=0;//失败次数的记录
String nowdic="";
String nowmi="";
for(int i=0;i<mi.size();i++){
//System.out.println("mi.get0="+mi.get(i).toString());
String [] mii=mi.get(i).toString().split(" ");//将密文以空格分开保存到数组中
//System.out.println(mii.length);
int milength=mii.length;
first:while(mm<milength){//如果失败次数大于字典的数量,则退出
misign=mm;
dicsign=sign;
second:while(dicsign<milength){//对每一个单词匹配所有的密文
if(usedic.contains(dic[dicsign])){//如果该单词已经被匹配过,则向后移动
dicsign++;
if(dicsign==num){
break first;
}
}else{
nowdic=dic[dicsign];
while(misign<mii.length){
if(usemi.contains(mii[misign])){//如果该密文被匹配过,则向后移动
misign++;
if(misign==milength){
usedic.clear();
usemi.clear();
map.clear();
mm++;
misign=0;
sign=0;
continue first;
}
}else{
nowmi=mii[misign];
if(mii[misign].length()==dic[dicsign].length()){//首先判断密文中的第k段是否与字典中的第j为长度相同
for(int a=0;a<mii[misign].length();a++){//如果相同的话,则对两个段用map一一对应
if(map.containsKey(String.valueOf(dic[dicsign].charAt(a)))){//查看map中是否已经包含了该键
if(!map.get(String.valueOf(dic[dicsign].charAt(a))).equals(String.valueOf(mii[misign].charAt(a)))){
b=true;
}
}
}
if(!b){
for(int a=0;a<mii[misign].length();a++){//如果相同的话,则对两个段用map一一对应
map.put(String.valueOf(dic[dicsign].charAt(a)), String.valueOf(mii[misign].charAt(a)));//不包含则添加
// System.out.println(map.toString());
}
mapp.clear();
Iterator<String> iter=map.keySet().iterator();
while(iter.hasNext()){
String key=iter.next();
mapp.put((String)map.get(key),key);
}
}else{
misign++;
b=false;
if(misign==milength){
//清空所有的记录,重新开始
usedic.clear();
usemi.clear();
map.clear();
mm++;
misign=0;
sign=0;
continue first;
}else{
continue second;
}
}
//将映射过的密文和单词存入到链表中
usedic.add(dic[dicsign]);
usemi.add(mii[misign]);
misign=0;
sign++;
if(sign==milength){
break first;
}
continue second;
}else{
misign++;
if(misign==milength){
usedic.clear();
usemi.clear();
map.clear();
mm++;
misign=0;
sign=0;
continue first;
}
}
}
}
}
}
//System.out.println(" "+map.toString());
}
//格式打印
// Iterator<String> iter=map.keySet().iterator();
// while(iter.hasNext()){
// String key=iter.next();
// mapp.put((String)map.get(key),key);
// }
String stemp=mi.get(i).toString();
System.out.println(stemp);
//System.out.println(mapp.toString());
for(int kk=0;kk<stemp.length();kk++){
//System.out.print(stemp.charAt(kk));
//System.out.print(map.get(String.valueOf(stemp.charAt(kk)))+" ");
if(String.valueOf(stemp.charAt(kk)).equals(" ")){
System.out.print(" ");
}else{
if(map.isEmpty()){
System.out.print("*");
}else{
System.out.print(mapp.get(String.valueOf(stemp.charAt(kk))));
}
}
}
System.out.println();System.out.println();
//循环下一次前,清空数据
usedic.clear();
usemi.clear();
map.clear();
mm=0;
misign=0;
dicsign=0;
sign=0;
}
}
}
第一次写是用了四个小时,后来反馈过来有bug,又调试了一下发现是因为不满足条件的键值对也会存入到map中,然后就多做了一个校验,感觉还是回有bug,但是不知道出在哪里,目前来说自己测试的是没有bug的
一道笔试题,加密解密的
最新推荐文章于 2020-07-27 11:38:00 发布