一道笔试题,加密解密的

  
  
有一种常见但不安全的加密文本的方法, 是将字母表中的某个字母固定地取代另一个字母.
为了保证加密是可逆的, 没有两个字母会被同一个字母取代.
你的任务是要解密几行文本. 这几行文本在被加密的时候可能每一行都使用了不同的取代方案, 而且所有的单词都来自一个已知的词典.
输入:
输入文件包含多行. 第一行是一个整数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的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值