这个笔试还是前天做的了,这个题目当时没有写出来,这两天抽时间做了一下,在这里跟大家分享一下。
3、 我的思路
我觉得这个题目的难点在于如何将打乱之后的字符串还原成正确的单词序列。经过分析,发现复数数字对应的英文单词都有特征字母,其中0对应的ZERO的特征字母是Z,2对应的TWO的特征字母是W,4对应的FOUR的特征字母是U,6对应的SIX的特征字母是X,8对应的EIGHT的特征字母是G。将这5个数字排除之后,剩下的所有单数数字所对应的单词也可以找到特征字母了(排除5个复数之前这5个单数没办法找出特征字符),其中1对应的ONE的特征字母为O,3对应的THREE的特征字母为T,5对应的FIVE的特征字母为F,7对应的SEVEN的特征字母为S,最后剩下的就是9对应的单词NINE的字母了。
上面解决了把字符串还原成正确单词序列的问题,接下就就应该把单词转换成对应的实际的数字,然后对这些数组进行排序,最后输出即可。
4、 我的实现
import java.util.Arrays;
import java.util.Scanner;
public class Ti31
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.nextLine());
//获取输入数据
String[] inputString = new String[n];
for(int i=0; i//对数据进行解析
for(int k=0; kget = judge(inputString[k]);
char[] getChars = get.toCharArray();
Arrays.sort(getChars);
System.out.println(new String(getChars));
}
}
//根据特征字母判断
public static String judge(String input)
{
String getDigitString = ""; //存放实际对应的数字
while(input.length() > 0)
{
String key = "";
if(input.contains("G"))//8
{
key = "EIGHT";
}
else if(input.contains("Z"))//0
{
key = "ZERO";
}
else if(input.contains("W"))//2
{
key = "TWO";
}
else if(input.contains("U"))//4
{
key = "FOUR";
}
else if(input.contains("X"))//6
{
key = "SIX";
}
else if(input.contains("T"))//3
{
key = "THREE";
}
else if(input.contains("O"))//1
{
key = "ONE";
}
else if(input.contains("S"))//7
{
key = "SEVEN";
}
else if(input.contains("V"))//5
{
key = "FIVE";
}
else//9
{
key = "NINE";
}
getDigitString += getOrdinaryDigit(key);
//得到以上数字后将该数字对应的字母删除
input = removeChars(input,key);
}
return getDigitString;
}
//根据单词,还原数字
public static int getOrdinaryDigit(String input)
{
int digit = 0;
switch (input)
{
case "ZERO":
digit = 0;
break;
case "ONE":
digit = 1;
break;
case "TWO":
digit = 2;
break;
case "THREE":
digit = 3;
break;
case "FOUR":
digit = 4;
break;
case "FIVE":
digit = 5;
break;
case "SIX":
digit = 6;
break;
case "SEVEN":
digit = 7;
break;
case "EIGHT":
digit = 8;
break;
case "NINE":
digit = 9;
}
if(digit >= 8)
{
digit = digit - 8;
}
else
{
digit = 2 + digit;
}
return digit;
}
//删除相应数字对应单词的字母
public static String removeChars(String input, String key)
{
String vaString = input;
String newString = "";
switch (key)
{
case "ZERO":
newString = vaString.replaceFirst("Z", "").replaceFirst("E", "").replaceFirst("R", "").replaceFirst("O", "");
break;
case "ONE":
newString = vaString.replaceFirst("O", "").replaceFirst("N", "").replaceFirst("E", "");
break;
case "TWO":
newString = vaString.replaceFirst("T", "").replaceFirst("W", "").replaceFirst("O", "");
break;
case "THREE":
newString = vaString.replaceFirst("T", "").replaceFirst("H", "").replaceFirst("R", "").replaceFirst("E", "").replaceFirst("E", "");
break;
case "FOUR":
newString = vaString.replaceFirst("F", "").replaceFirst("O", "").replaceFirst("U", "").replaceFirst("R", "");
break;
case "FIVE":
newString = vaString.replaceFirst("F", "").replaceFirst("I", "").replaceFirst("V", "").replaceFirst("E", "");
break;
case "SIX":
newString = vaString.replaceFirst("S", "").replaceFirst("I", "").replaceFirst("X", "");
break;
case "SEVEN":
newString = vaString.replaceFirst("S", "").replaceFirst("E", "").replaceFirst("V", "").replaceFirst("E", "").replaceFirst("N", "");
break;
case "EIGHT":
newString = vaString.replaceFirst("E", "").replaceFirst("I", "").replaceFirst("G", "").replaceFirst("H", "").replaceFirst("T", "");
break;
case "NINE":
newString = vaString.replaceFirst("N", "").replaceFirst("I", "").replaceFirst("N", "").replaceFirst("E", "");
}
return newString;
}
}
5、 改进思路
以上解法是笔试的时候的思路,可以看出实现起来还是很繁琐。过后我跟同学交流的时候,同学提到用统计字母出现次数的方法来解这个题目。根据这个想法,我对以上解法进行了一定的改进。主要改进的地方在于首先对各字母的出现次数进行统计,存放在Map<字母,出现次数>里。这样就可以一次性将同一个数字一次取出,而不用逐次取出。并且,取完一个数字之后,只需要将相应字母的出现次数减去相应次数,而不用对字符串进行操作,这样大大的提高了效率。
6、 改进后的实现
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
public class Ti32
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
int n = Integer.parseInt(scanner.nextLine());
//获取输入数据
String[] inputString = new String[n];
for(int i=0; i//对数据进行解析
for(int k=0; kchar[] digitChars = digitString.toCharArray();
Arrays.sort(digitChars);
System.out.println(new String(digitChars));
}
}
//统计各个字母出现的次数
public static Map countCharNum(String input)
{
char[] inputChar = input.toCharArray();
Map charNumMap = new HashMap<>();
for(char c : inputChar)
{
if(!charNumMap.containsKey(c))
{
charNumMap.put(c, 1);
}
else
{
int count = charNumMap.get(c);
charNumMap.put(c, count+1);
}
}
return charNumMap;
}
//根据特征字母进行匹配单词
//根据特征字母判断
public static String judge(Map charNumMap)
{
String getDigitString = ""; //存放实际对应的数字
while(charNumMap.size() > 0)
{
String key = "";
int keyCount = 0;
if(charNumMap.containsKey('G'))//8
{
key = "EIGHT";
keyCount = charNumMap.get('G');
}
else if(charNumMap.containsKey('Z'))//0
{
key = "ZERO";
keyCount = charNumMap.get('Z');
}
else if(charNumMap.containsKey('W'))//2
{
key = "TWO";
keyCount = charNumMap.get('W');
}
else if(charNumMap.containsKey('U'))//4
{
key = "FOUR";
keyCount = charNumMap.get('U');
}
else if(charNumMap.containsKey('X'))//6
{
key = "SIX";
keyCount = charNumMap.get('X');
}
else if(charNumMap.containsKey('T'))//3
{
key = "THREE";
keyCount = charNumMap.get('T');
}
else if(charNumMap.containsKey('O'))//1
{
key = "ONE";
keyCount = charNumMap.get('O');
}
else if(charNumMap.containsKey('S'))//7
{
key = "SEVEN";
keyCount = charNumMap.get('S');
}
else if(charNumMap.containsKey('V'))//5
{
key = "FIVE";
keyCount = charNumMap.get('V');
}
else ///9
{
key = "NINE";
keyCount = charNumMap.get('E');
}
int theDigit = getOrdinaryDigit(key);//根据单词还原数字
for(int j=0; j//将相应字母的次数减去keyCount
removeChars(charNumMap, key, keyCount);
}
return getDigitString;
}
//根据单词,还原数字
public static int getOrdinaryDigit(String input)
{
int digit = 0;
switch (input)
{
case "ZERO":
digit = 0;
break;
case "ONE":
digit = 1;
break;
case "TWO":
digit = 2;
break;
case "THREE":
digit = 3;
break;
case "FOUR":
digit = 4;
break;
case "FIVE":
digit = 5;
break;
case "SIX":
digit = 6;
break;
case "SEVEN":
digit = 7;
break;
case "EIGHT":
digit = 8;
break;
case "NINE":
digit = 9;
}
if(digit >= 8)
{
digit = digit - 8;
}
else
{
digit = 2 + digit;
}
return digit;
}
//移除该数字对应单词*keyCount
public static void removeChars(Map charNumMap, String key, int keyCount)
{
char[] keyChars = key.toCharArray();
for(char c : keyChars)
{
int newCount = charNumMap.get(c)-keyCount;
if(newCount == 0)
{
charNumMap.remove(c);
}
else
{
charNumMap.put(c, newCount);
}
}
}
}
7、 总结
如果看代码量,好像改进之后的方法并没有更简单,但是效率上却有非常大的提升。我用11885个字符组成的字符串进行了测试对比,解法一所耗时间为292ms,解法二所耗时间为29ms,10倍的差距。以上实现没有经过OJ平台测试,所以我也不能保证绝对正确,写在这里仅供大家参考。
以上是我的两种解法,总体感觉还是很繁琐。如果哪位大神有更好的解法,希望不吝赐教,不胜感激!