public class Main4 {
//定义输入字的长度,根据题意,长度为8,也就是用8个16进制的数来表示一个字
public static int WORD_STRING_LENGTH=8;
//一个字占32bit,用32位二进制数来表示
public static int BIT_LIST_LENGTH=4*WORD_STRING_LENGTH;
//定义二进制与十进制对应的数组
public static int PATTERN_LENGTH=16;
public static String[] bitList={
"0000","0001","0010","0011",
"0100","0101","0110","0111",
"1000","1001","1010","1011",
"1100","1101","1110","1111"};
public static String hexList="0123456789abcdef";
public static void main(String[] args) {
System.out.println("运行时间达七小时,请耐心等候…………");
String [][] distribution=new String [PATTERN_LENGTH][PATTERN_LENGTH];
distribution=getDistribution(PATTERN_LENGTH);
printResult(distribution);
}
/*
该方法实现线性变换模块。要求:用户输入一个用16进制表示的数字(例如 1a2b3c4d)
程序输出相应的用16进制表示的字
*/
private static String getResult(String str){
int[] B=new int[BIT_LIST_LENGTH];//用于存储输入字转为二进制的数
int[] LB=new int[BIT_LIST_LENGTH];//用于存储得到的二进制结果
String LB_16="";//用于存储得到的十六进制结果
//进行一次循环,将输入的十六进制的数转化为二进制的数
for(int i=0;i<WORD_STRING_LENGTH;i++){
int k=Integer.valueOf(str.substring(i,i+1),16);
for(int j=0;j<4;j++){
B[4*i+j]=bitList[k].charAt(j)-48;
}
}
//进行线性变换操作
for(int p=0;p<BIT_LIST_LENGTH;p++){
LB[p]=B[p]^
B[(p+2)%BIT_LIST_LENGTH]^
B[(p+10)%BIT_LIST_LENGTH]^
B[(p+18)%BIT_LIST_LENGTH]^
B[(p+24)%BIT_LIST_LENGTH];
}
//将二进制的数转换为十六进制的数
for(int x=0;x<WORD_STRING_LENGTH;x++){
String temp="";
for(int y=0;y<4;y++){
temp+=LB[x*4+y];
}
LB_16+=Integer.toHexString(Integer.parseInt(temp, 2));
}
return LB_16;
}
/*
输入两个十进制的数,返回两个十六进制的数组成的字符串
*/
private static String getTwoHex(int i,int j){
String str= hexList.substring(i,i+1)+hexList.substring(j,j+1);
return str;
}
/*
定义了模式函数,输入的是一个字,四个字节,八个十六进制的数,
每两个十六进制的数为一个字节,如果两个字节的数都为0,则该字节为零
对输入的四个字节进行判断,如果该字节为0则用一个0定义该字节,
如果该字节不为0,则用1定义该字节
例如输入:00001a2b ,则输出为:0011
*/
private static String pattern(String str){
String pat="";
for (int i=0;i<str.length()/2;i++){
if(str.substring(2*i,2*(i+1)).equals("00")||
str.substring(2*i,2*(i+1))=="00"){
pat+="0";
}
else {
pat+="1";
}
}
return pat;
}
private static String[][] getDistribution(int n){
long sum[]=new long[n+1];
long count[][]=new long[n+1][n+1];
String result[][]=new String [n+1][n+1];
//对每一种情况进行操作,操作时候可以将情况分为4类
for(int x=1;x<n;x++){
int item=getItem(x);
switch (item){
case 1://只包含一个1的情况
for (int i = 0; i <16; i++) {
for (int j = 0; j < 16; j++) {
if (!(i == 0 && j == 0)){
sum[x]++;
String twoHex1 = getTwoHex(i, j);
String str= "000000" + twoHex1;
String pat=pattern(getResult(str));
int index=Integer.parseInt(pat, 2);
count[x][index]++;
}
}
}
break;
case 2://包含两个1的情况
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
if (!((i == 0 && j == 0) || (l == 0 && k == 0) )) {
sum[x]++;
String twoHex1 = getTwoHex(i, j);
String twoHex2 = getTwoHex(k, l);
String str = "0000" + twoHex1 + twoHex2;
String pat = pattern(getResult(str));
int index = Integer.parseInt(pat, 2);
count[x][index]++;
}
}
}
}
}
break;
case 3://包含三个1的情况
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
for (int a = 0; a < 16; a++) {
for (int b = 0; b < 16; b++) {
if (!((i == 0 && j == 0) || (l == 0 && k == 0) || (a == 0 && b == 0))) {
sum[x]++;
String twoHex1 = getTwoHex(i, j);
String twoHex2 = getTwoHex(k, l);
String twoHex3 = getTwoHex(a, b);
String str = "00" + twoHex1 + twoHex2 + twoHex3;
String pat=pattern(getResult(str));
int index=Integer.parseInt(pat, 2);
count[x][index]++;
}
}
}
}
}
}
}
break;
case 4://包含四个1的情况
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
for (int a = 0; a< 16; a++) {
for (int b = 0; b< 16; b++) {
for (int p = 0; p < 16; p++) {
for (int q = 0; q < 16; q++) {
if (!((i == 0 && j == 0) || (l == 0 && k == 0) ||
(a == 0 && b == 0)||(p == 0 && q == 0))){
sum[x]++;
String twoHex1 = getTwoHex(i, j);
String twoHex2 = getTwoHex(k, l);
String twoHex3 = getTwoHex(a, b);
String twoHex4 = getTwoHex(p, q);
String str = twoHex1 + twoHex2 + twoHex3+ twoHex4;
String pat=pattern(getResult(str));
int index=Integer.parseInt(pat, 2);
count[x][index]++;
}
}
}
}
}
}
}
}
}
break;
}
}
for(int r=0;r<=n;r++){
for(int s=0;s<=n;s++){
if(count[r][s]==0){
result[r][s]="0";
}
else{
result[r][s]=String.valueOf(count[r][s]/255)+"/"+sum[r]/255;
}
}
}
return result;
}
/*
给出十进制的数,判断其四位二进制数中1的个数
*/
private static int getItem(int x){
String str=bitList[x];
int count=0;
for(int i=0;i<4;i++){
if(str.charAt(i)=='1'){
count++;
}
}
return count;
}
private static void printResult(String[][] list){
int[] sequence={0,1,2,4,8,3,5,6,9,10,12,7,11,13,14,15};
System.out.printf("%-5s"," ");
for(int i=1;i<list.length-1;i++){
String str=bitList[sequence[i]];
System.out.printf("%-20s",str);
}
System.out.println();
for(int r=1;r<list.length-1;r++) {
System.out.printf("%-5s",bitList[sequence[r]]);
for (int s = 1; s < list.length-1; s++) {
String str=list[sequence[r]][sequence[s]];
System.out.printf("%-20s",str);
}
System.out.println();
}
}
}