[算法]华为笔试题——拼音与英文转换
题目描述:
编写拼音与英文转换的函数,如果输入号码是英文,转成拼音,如果是拼音,转成英文,例如输入OneZeroDoubleThree,则输出YiLingSanSan。
拼音、英文见下表:
Yi Er San Si Wu Liu Qi Ba Jiu Ling
One Two Three Four Five Six Seven Eight Nine Zero
注意:每个单词均为首字母大写,遇到连续两个相同数字,输入可以前面加Double,输出不可以加Double。
输入描述:
由首字母大写的字符串,字符输入范围是0,1,2,3,4,5,6,7,8,9的英文单词或者中文拼音。
输出描述:
如果输入是英文单词,输出拼音。如果输入是拼音,输出英文单词。不能混合出现,输入非法,输出ERROR。
示例:
输入:
OneTwoDoubleThree
输出:
YiErSanSan
思路:首先,分词,根据大写字母将字符串进行分词。然后,进行匹配和替换,着重考虑一下Double。最后,处理各种非法情况。
代码:
package com; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Scanner; import java.util.Set; public class Test { static String[] english = {"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine"}; static String[] pinyin = {"Ling", "Yi", "Er", "San", "Si", "Wu", "Liu", "Qi", "Ba", "Jiu"}; static List<String> elist = new ArrayList<String>(); static List<String> plist = new ArrayList<String>(); static { for (int i = 0; i < english.length; i++) { elist.add(english[i]); plist.add(pinyin[i]); } } public static void main(String[] args) { int flag = 1;//代表正常情况,为0代表输出ERROR Scanner scanner = new Scanner(System.in); String s = scanner.nextLine(); /** * 如果输入全是小写字母直接报错 */ if(s.matches("[a-z]{1,}")){ flag = 0; } String s1 = s.replaceAll("[A-Z]", " $0");// 正则替换注意“ $0”前面有个空格 String[] split = s1.split(" "); String[] split2 = new String[split.length - 1]; System.arraycopy(split, 1, split2, 0, split2.length);//因为split切分完多出了一个空的字符(首位),现在把它去掉 try { for (int i = 0; i < split2.length; i++) { if(elist.contains(split2[i])){ int index = elist.indexOf(split2[i]); split2[i] = split2[i].replace(split2[i], plist.get(index)); }else if(plist.contains(split2[i])){ int index = plist.indexOf(split2[i]); split2[i] = split2[i].replace(split2[i], elist.get(index)); }else if (split2[i].equals("Double")) { split2[i] = split2[i + 1]; if(elist.contains(split2[i])){ int index = elist.indexOf(split2[i]); split2[i] = split2[i].replace(split2[i], plist.get(index)); }else if(plist.contains(split2[i])){ int index = plist.indexOf(split2[i]); split2[i] = split2[i].replace(split2[i], elist.get(index)); }else{ /** * 出现DoubleDouble的情况 */ flag = 0; } }else{ flag = 0; } } } catch (Exception e) { /** * 抛出异常是因为有一种只出现Double的情况 */ flag = 0; } /** * 这里通过set的个数进行判断,因为最后只能出现要么都是英语,要么都是拼音,两者一旦混合出现就不对了 */ Set<Integer> set = new HashSet<Integer>(); for (int i = 0; i < split2.length; i++) { set.add(judge(split2[i])); } if(set.size() > 1){ flag = 0; } StringBuilder sb = new StringBuilder(""); if(flag == 1){ for (int j = 0; j < split2.length; j++) { sb.append(split2[j]); } }else{ sb.append("ERROR"); } System.out.println(sb.toString()); } /** * 判断一个字符串是属于英语数字还是拼音数字还是什么也不是 * @param string * @return 英语数字返回0,拼音数字返回1,否则返回-1 */ public static int judge(String string){ int ret = -1; if(elist.contains(string)){ ret = 0; }else if(elist.contains(string)){ ret = 1; } return ret; } }
正则表达式中$1,$2...是表示的小括号里的内容 $1是第一个小括号里的 ,$2是第2个小括号里的 比如 /gai([\w]+?)over([\d]+)/ 匹配 gainover123 $1= 括号里的 n $2= 第2个括号里的 123,$0表示所有。