我曾经在博客中详细解过这个题目,具体地址为http://www.cnblogs.com/guozhenqiang/p/5441137.html,读者先看完那篇文章,
再看下面的内容:
今天又来谈论这个问题,今天的问题和之前那个很相像,只有一点不同,那就是要求编码后的每个字符串首位不能出现0,那就意味着不能
给所有字符串首位出现的字符编码为0,那么我们应该怎么办呢?
我的解法是这样的,还是之前的做法,在编好码之后,先不要急于计算总和,而是需要再建立一个10个元素的字符数组ch2[10],把所有的
字符串的首字母找出来,放到刚建立的字符数组ch2[]中,另外设立一个指针q=0,然后把当前编码为0的字符去该字符数组中查找,如果存在就将
该字符与编码为(++q)的字符进行替换,替换完之后,再从头开始开始扫描,直到不存在为止。
改进后的Java代码如下:
1 import java.util.*; 2 public class Main8 { 3 public static void main(String[] args) { 4 // TODO 自动生成的方法存根 5 Scanner scan=new Scanner(System.in); 6 int n=Integer.parseInt(scan.nextLine()); //读入n 7 String str[]=new String[n]; 8 int maxLength=0; 9 for(int i=0;i<n;i++) //读入每个字符串,并统计出最长的字符串的长度 10 { 11 str[i]=scan.nextLine(); 12 if(str[i].length()>maxLength)maxLength=str[i].length(); 13 } 14 int a[][]=new int[10][maxLength]; //开出一个10*最大长度的二维数组 15 for(int i=0;i<n;i++) 16 { 17 if(str[i].length()<maxLength) 18 { int length=str[i].length(); 19 for(int j=0;j<maxLength-length;j++) //把长度不够最大长度的字符串的前面补上无关的任意字符,这里我补的是@字符 20 str[i]="@"+str[i]; 21 } 22 for(int j=0;j<maxLength;j++) //统计每个字符串每个位上出现字符的频率,放到频率数组a[][]中 23 if(str[i].charAt(j)!='@') //如果是我之前补得无关字符,则忽略 24 a[str[i].charAt(j)-'A'][j]++; 25 } 26 long b[]=new long[10]; //开辟一个用来存储每个字符的单位和 27 char ch[]={'A','B','C','D','E','F','G','H','I','J'}; //用来和b[]绑定,用来记忆每个字符的位置,因为后面要对b[]排序 28 for(int i=0;i<=9;i++) //统计出每个字符出现的基数综合 29 for(int j=0;j<maxLength;j++) 30 b[i]=b[i]*10+a[i][j]; 31 32 for(int i=0;i<9;i++) //把每个字符的基数值总和进行排序 33 for(int j=i+1;j<10;j++) 34 if(b[i]>b[j]){ 35 long t=b[i]; 36 b[i]=b[j]; 37 b[j]=t; 38 char c=ch[i]; 39 ch[i]=ch[j]; 40 ch[j]=c; 41 } 42 43 char ch2[]=new char[10]; 44 for(int i=0;i<n;i++) //将每个字符串的首字母找出来放到ch2[]中 45 for(int j=0;j<maxLength;j++) 46 if(str[i].charAt(j)!='@'){ 47 ch2[str[i].charAt(j)-'A']=str[i].charAt(j); 48 break; 49 } 50 int q=0; //附设一个指针 51 for(int i=0;i<10;i++) 52 if(ch2[i]==ch[0]){ //如果存在,就和编码非0最小的字符交换 53 char c=ch[0]; 54 ch[0]=ch[++q]; 55 ch[q]=c; 56 long t=b[0]; 57 b[0]=b[q]; 58 b[q]=t; 59 i=-1; //归位,再从头开始扫描 60 } 61 62 long sum=0; //用来计算最终的总和 63 for(int i=0;i<=9;i++) 64 { 65 System.out.print(i+"对应"+ch[i]+", "); //输出每个数字对应的字符 66 sum=sum+b[i]*i; 67 } 68 System.out.println(); 69 70 System.out.println("总和为:"+sum); 71 } 72 73 }
测试样例输出结果为:
2
ABC
BCDAA
0对应E, 1对应F, 2对应G, 3对应H, 4对应I, 5对应J, 6对应D, 7对应A, 8对应C, 9对应B,
总和为:99475