该题主要研究编码文本的输入问题。需考虑3个问题:(1)代表每个小节长度的字符编码,只可能有8种长度的情况(0,1,2,3,4,5,6,7),根据字符编码获得一个长度,接下来利用固定长度截取字符编码,直到碰到固定长度的‘1‘’就结束该小节,再截取3个字符编码获取下一个小节的长度。(2)判断每一行字符编码的可能性,比如,能不能得到键串编码,能不能得到固定长度的字符编码,行尾遇到结束字符该怎么办,行尾遇到长度编码为0怎么办。(3)行尾有一个空格,要注意清除,因为我使用的是nextLine()输入,需要考虑行尾是否有空格。
另外,每次截取的固定长度的字符编码只要不为结束编码,则需要与我之前打好的表做对比,找到对应的字符保存到答案字符串里面。说到打表,因为题目限制键串最长为7,所以表数据最多只有248个,因此可以输入前就打好,可以减少后面找答案字符需要的时间。
代码如下:
import java.util.Scanner;
public class Main {
static String formStr[]=new String[300];
static String keyStr[]={"000","001","010","011","100","101","110","111"};
public static void main(String arg[]){
Scanner reader = new Scanner(System.in);
while(reader.hasNext()){
String resultStr="";
String ss=reader.nextLine();
form(ss.length());
boolean key=true;
String sumStr=""; //定义一个总长度的编码文本字符串
int startint=0; //定义键串编码长度的开始
int overint=0; //定义键串编码长度的结尾
int beginInt=0; //定义截取编码长度的开始
int endInt=0; //定义截取编码长度的结尾
String lengthStr=""; //代表编码长度的字符串
int lengthInt=-1; //用于得到键串长度 以判断后面的编码 且得到结束字符编码
String endStr=""; //定义字符编码 用于判断字符编码为全1时结束
int sumInt=0; //定义总长度
while(true){
String s=reader.nextLine();
if(s.length()==0)
continue;
else if(" ".equals(s.substring(s.length()-1,s.length()))){
sumStr+=s.substring(0,s.length()-1);
sumInt+=s.substring(0,s.length()-1).length();
}
else{
sumStr+=s;
sumInt+=s.length();
}
if(key&&sumInt-3>=0){
lengthStr="";
endStr="";
key=false;
//截取代表编码长度的字符串
lengthStr=sumStr.substring(startint,overint+3);
sumInt-=3;
beginInt=endInt=startint+3;
//得到键串的长度
for(int i=0;i<8;i++){
if(keyStr[i].equals(lengthStr))
lengthInt=i;
}
if(lengthInt==0) //代表编码长度的字符串为0 跳出输入
break;
//得到结束字符编码
for(int i=1;i<=lengthInt;i++)
endStr+="1";
}
//用于判断该行字符串是否输入了结束编码
while(sumInt-lengthInt>=0&&lengthInt>0&&key==false){
String panduanStr=sumStr.substring(beginInt,endInt+lengthInt);
beginInt+=lengthInt;
endInt=startint=overint=beginInt;
sumInt-=lengthInt;
if(panduanStr.equals(endStr)){ //碰到了结束编码
key=true;
if(sumInt-3>=0){ //是否够得到下一个代表编码长度的字符串
lengthStr="";
lengthInt=0;
endStr="";
key=false;
lengthStr=sumStr.substring(startint,overint+3);
//得到键串的长度
for(int i=0;i<8;i++){
if(keyStr[i].equals(lengthStr))
lengthInt=i;
}
if(lengthInt==0) //代表编码长度的字符串为0 跳出输入
break;
//等到结束字符编码
for(int i=1;i<=lengthInt;i++)
endStr+="1";
sumInt-=3;
beginInt=endInt=overint+3;
}
else //否则输入下一行
break;
}
else{
for(int i=0;i<ss.length();i++){
if(panduanStr.equals(formStr[i])){
resultStr+=ss.substring(i,i+1);
break;
}
}
}
}
if(lengthInt==0)
break;
}//一组数据结束 并输出
System.out.println(resultStr);
}// 所有数据结束
reader.close();
}
public static void form(int a){
if(a>0) //1位 1
formStr[0]="0";
if(a>1){ //2位 4
formStr[1]="00";
for(int i=1;i<=2;i++){
String ts=Integer.toBinaryString(i);
if(i<2)
formStr[i+1]="0"+ts;
else
formStr[i+1]=ts;
}
}
if(a>4){ //3位 11
formStr[4]="000";
for(int i=1;i<=6;i++){
String ts=Integer.toBinaryString(i);
if(i<2)
formStr[i+4]="00"+ts;
else if(i<4)
formStr[i+4]="0"+ts;
else
formStr[i+4]=ts;
}
}
if(a>11){ //4位 26
formStr[11]="0000";
for(int i=1;i<=14;i++){
String ts=Integer.toBinaryString(i);
if(i<2)
formStr[i+11]="000"+ts;
else if(i<4)
formStr[i+11]="00"+ts;
else if(i<8)
formStr[i+11]="0"+ts;
else
formStr[i+11]=ts;
}
}
if(a>26){ //5位 57
formStr[26]="00000";
for(int i=1;i<=30;i++){
String ts=Integer.toBinaryString(i);
if(i<2)
formStr[i+26]="0000"+ts;
else if(i<4)
formStr[i+26]="000"+ts;
else if(i<8)
formStr[i+26]="00"+ts;
else if(i<16)
formStr[i+26]="0"+ts;
else
formStr[i+26]=ts;
}
}
if(a>57){ //6位 120
formStr[57]="000000";
for(int i=1;i<=62;i++){
String ts=Integer.toBinaryString(i);
if(i<2)
formStr[i+57]="00000"+ts;
else if(i<4)
formStr[i+57]="0000"+ts;
else if(i<8)
formStr[i+57]="000"+ts;
else if(i<16)
formStr[i+57]="00"+ts;
else if(i<32)
formStr[i+57]="0"+ts;
else
formStr[i+57]=ts;
}
}
if(a>120){ //7位 247
formStr[120]="0000000";
for(int i=1;i<=126;i++){
String ts=Integer.toBinaryString(i);
if(i<2)
formStr[i+120]="000000"+ts;
else if(i<4)
formStr[i+120]="00000"+ts;
else if(i<8)
formStr[i+120]="0000"+ts;
else if(i<16)
formStr[i+120]="000"+ts;
else if(i<32)
formStr[i+120]="00"+ts;
else if(i<64)
formStr[i+120]="0"+ts;
else
formStr[i+120]=ts;
}
}
}
}
若有其他疑问,可以评论留言