小米2017年校园招聘笔试题第三题

这个笔试还是前天做的了,这个题目当时没有写出来,这两天抽时间做了一下,在这里跟大家分享一下。

1、 题目
这里写图片描述

2、 输入输出要求及样例
输入输出要求:
这里写图片描述

样例:
这里写图片描述

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<n; i++)
        {
            inputString[i] =  scanner.nextLine();   
        }

        //对数据进行解析
        for(int k=0; k<n; k++)
        {           
            String get = 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<n; i++)
        {
            inputString[i] =  scanner.nextLine();   
        }

        //对数据进行解析
        for(int k=0; k<n; k++)
        {               
            String digitString = judge(countCharNum(inputString[k]));

            char[] digitChars = digitString.toCharArray();

            Arrays.sort(digitChars);

            System.out.println(new String(digitChars));
        }   
    }


    //统计各个字母出现的次数
    public static Map<Character,Integer> countCharNum(String input)
    {       
        char[] inputChar = input.toCharArray();

        Map<Character,Integer> 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<Character,Integer> 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; j++)
            {
                getDigitString += theDigit;
            }       

            //将相应字母的次数减去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<Character,Integer> 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平台测试,所以我也不能保证绝对正确,写在这里仅供大家参考。
以上是我的两种解法,总体感觉还是很繁琐。如果哪位大神有更好的解法,希望不吝赐教,不胜感激!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值