一道笔试题,加密解密的

原创 2013年12月05日 14:32:41
有一种常见但不安全的加密文本的方法, 是将字母表中的某个字母固定地取代另一个字母.
为了保证加密是可逆的, 没有两个字母会被同一个字母取代.
你的任务是要解密几行文本. 这几行文本在被加密的时候可能每一行都使用了不同的取代方案, 而且所有的单词都来自一个已知的词典.
输入:
输入文件包含多行. 第一行是一个整数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的

相关文章推荐

搜狗笔试题——加密解密

public class Test { public static void encode(byte[] in, byte[] out, int password) { in...
  • B_H_L
  • B_H_L
  • 2012年09月26日 10:24
  • 1121

RSA加密解密IP核设计开题报告

  • 2012年03月21日 20:32
  • 40KB
  • 下载

第二届360杯全国大学生信息安全技术大赛部分解题思路(加密解密题)

第二届360杯全国大学生信息安全技术大赛比赛的题目如下: 加密解密第一题: 源码如下: var qrivy = eval;NanylmrgurXrl="7D6A7...

第二届360杯全国大学生信息安全技术大赛部分解题思路(加密解密题)

WEB安全第一题 解题攻略: 验证码设计bug,抓取发送验证码链接,然后查看response发现验证码在response里。打开题目链接发现是注册的界面,邮箱固定为360-question...

谈谈一道js笔试题,涉及作用域链、闭包

题如下,让你写出输出结果: function test(){ var n=4399; function add(){ n++; console.log(...

一道笔试题,求给定一个整数是否存在一个给定的矩阵中

给出一个矩阵,有下列特点:每行严格递增,每列严格递增,矩阵内没有重复元素        如:1   2    4     12                3   5    9     15 ...
  • skip_yj
  • skip_yj
  • 2013年06月18日 20:36
  • 354

找工作练手--一道腾讯的笔试题

今日,在网上搜到一篇讲述在腾讯面经。里面有道题,考的是生产者消费者问题。题目如下: 模拟线程间通信:线程A和B共用一块空间C[] space, 模拟一次线程间的通信:线程A生产一个C物品,并把它放入...
  • rein07
  • rein07
  • 2011年08月24日 09:58
  • 885

一道有意思的2012搜狗笔试题

【数据结构类】一种计算机,其有如下原子功能: 1. 赋值:a=b 2.+1:   ++a  ; a+1; 3. 循环,但只支持按次数的循环              for( 变量名){  ...

【Basic Code】一道“单例”的笔试题

题目:设计一个类,只能生成该类的一个实例。         面试过程中,对于“设计模式”这块,由于“单例”非常具有代表性,同时代码量不大,实现起来比较简单,经常会被放到笔试部分让应聘者手写,   ...

一道排序笔试题,在o(n)时间内对一个数组进行排序

题目:某公司有几万名员工,请完成一个时间复杂度为O(n)的算法对该公司员工的年龄作排序,可使用O(1)的辅助空间。 分析:估计有很多人应该都看过这个题目,仅仅作为自己面试找工作的一个记录哈,大家见笑...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:一道笔试题,加密解密的
举报原因:
原因补充:

(最多只允许输入30个字)