数不了。可以使用给定的输入字符串创建单词

时间:2016-09-18 05:49:38

标签: java java-8

我想打印出来的字符'hello'可以从给定的字符输入中打印出来。你可以建议我做错了吗,因为这段代码没有通过所有测试用例。

int fromDegrees = getResources().getInteger(R.integer.from_degrees);
int toDegrees = getResources().getInteger(R.integer.to_degrees);

我怎么能重构这段代码?

4 个答案:

答案 0 :(得分:2)

你的代码看起来很好;但它的主要问题是:它非常低级,因此难以阅读。

你看,所有这些计数器和数组访问......都不太好。而且:你非常硬编码“hello”到你的代码中。如果您的任务将是对某些任意单词进行检查,该怎么办?

所以,让我们为您提供一些有关如何改进代码的见解。

您可以使用Map<Character, Integer>来记住打印特定单词所需的字符:

String wordToCount = "hello"; // or maybe: coming form the user!
Map<Character, Integer> numberOfRequiredCharsPerChar = new HashMap<>();

for (char charToCount : wordToCount.toCharArray()) {
  if (!numberOfRequiredCharsPerChar.containsKey(charToCount)) {
    // unknown char, so we need a counter for it
    numberOfRequiredCharsPerChar.put(charToCount, new Integer(0));
  }
  int currentCounter = numberOfRequiredCharsPerChar.get(charToCount);
  numberOfRequiredCharsPerChar.put(charToCount, currentCounter+1);
}

所以:上面的内容迭代了“第一个”输入,之后,就像“hello”一样,Map会告诉你打印它需要什么:

h x 1,e x 1,ll x 2,o x 1。

然后,在第二步中,我们以相反的方式使用该地图的副本

int possibleCounts = 0;
String inputToCountOn = ....

Map<Character, Integer> numberOfUsedCharacters= new HashMap<>(numberOfRequiredCharsPerChar);

for (char availableChar : inputToCountOn()) {
  if (numberOfUsedCharacters.containsKey(availableChar)) {
    int currentCounter = numberOfUsedCharacters.get(availableChar);
    currentCounter--;
    if (currentCounter == 0) {
      numberOfUsedCharacters.remove(availableChar);
    } else {
      numberOfUsedCharacters.put(availableChar, currentCounter);
    }
    if (umberOfUsedCharacters.isEmpty()) {
      // that means: we fetched ALL chars we need to print the word ONCE
      possibleCounts++;
      // and reset our "counter" map
      numberOfUsedCharacters= new HashMap<>(numberOfRequiredCharsPerChar);
   }
}
... now you just print possibleCounts ...

当然,这看起来比你的输入更复杂;但它更灵活。如果花一些时间为每个活动创建小帮助方法,你可以用一种非常易读的方式写下整个事情。

答案 1 :(得分:1)

这是另一种选择。关于它的一些评论:
我使用GhostCat的方法来映射输入中每个字符的出现次数。
如果输入中有所需的字符,我会递归检查。
如果是这样,我从输入字符串中删除这些字符,然后再次检查。
解决方案区分大小写。

import java.util.HashMap;
import java.util.Map;

public class Test {

    static String word = "hello";
    static String strInput;

    public static void main(String[] args)  {

        strInput  = "hoe4olelltohlemllhlhoslelo";//read the string

        Map<Character, Integer> charMap = mapNumOfChars();
        int count = 0;
        boolean done= false;
        while(!done) {

            for(Character c : charMap.keySet()) {

                if(! hasTheNeededNumOfChars(c, charMap.get(c), 0)) {

                    done= true;
                }
            }

            if(!done ) {

                //remove from input string all chars that have been "used"
                removeAllCharsUsed();
                count++;
            }
        }

        System.out.println(count);
    }

    /**
     *Recursively search for num occurrences of c.
     *@param c
     *  char to search
     *@param num
     *  number of char occurrences
     *@param startFrom
     *  start searching from index
     *@return
     */
    private static boolean hasTheNeededNumOfChars(char c, int num, int startFrom) {

        int charIndex = strInput.indexOf(c, startFrom);

        //no occurances of char found
        if (charIndex < 0) {
            return false;
        }

        //if char found is last, or only one char occurrence needed
        //no need to continue checking
        if((charIndex == (strInput.length() -1)) || (num == 1) ) {

            return true;

        }else {

            //look for the remaining number of occurrences num-1
            //starting from index charIndex
            return hasTheNeededNumOfChars(c,num-1, charIndex+1);
        }
    }

    private static void removeAllCharsUsed() {

        for (char c : word.toCharArray()) {

            strInput = strInput.replaceFirst(String.valueOf(c),"");
        }
    }

    //taken from GhostCat solution
    private static Map<Character, Integer> mapNumOfChars() {

        Map<Character, Integer> charMap = new HashMap<>();

        for (char charToCount : word.toCharArray()) {

            if (!charMap.containsKey(charToCount)) {
                // unknown char, so we need a counter for it
                charMap.put(charToCount, new Integer(0));
            }
            int currentCounter = charMap.get(charToCount);
            charMap.put(charToCount, ++currentCounter);
        }

        return charMap;
    }
}

答案 2 :(得分:0)

if测试应该在for循环中:

public static void main(String[] args)  {

    String strInput  = br.readLine();//read the string 
    int count = 0;
    int h = 0,e = 0,l= 0,o = 0;

    for (int i=0; i< strInput.length();i++){

        if(strInput.charAt(i)=='h'){ h++;}
        else if(strInput.charAt(i)=='l'){l++;}
        else if(strInput.charAt(i)=='e'){e++;}
        else if(strInput.charAt(i)=='o'){o++;}

         //this test should be made with every loop 
        if((h>=1) && (e>=1) && (l>=2) && (o>=1)){
            count++;
            h--;
            e--;
            o--;
            l=l-2;
        }
    }
    System.out.println(count);
}

答案 3 :(得分:0)

这是一个针对您的问题的通用重构解决方案

主要思想是计算我们需要每个字符打印目标字的次数,然后查看我们可以在提供的输入中找到所需数量的次数。

例如:   如果我们想要打印AAB并且输入是AAABB,我们每次打印都需要2As和1B,因为我们只有3As,我们只能打印一次As,即使我们可以打印Bs两倍的As量会限制我们。

所以使用以下代码可以调用

timesCanBePrinted("hello","jhdfjhhelloejhlepoohhello");

你会得到答案2

private static int timesCanBePrinted(String targetWord, String letters) {

        Map<Character, Integer> targetWordMap = new HashMap<>();
        Map<Character, Integer> lettersWordMap = new HashMap<>();

        //initializing targetWordMap
        //so for hello for example our map will be like this
        //{h:1,e:1,l:2,o:1}
        initializeMapWithCharacterCount(targetWord, targetWordMap);
        initializeMapWithCharacterCount(letters, lettersWordMap);

        int timesCanBePrinted = Integer.MAX_VALUE;

        Map<Character, Integer> result = createMapWithNumberOfTimesWeCanUseEachCharacter(targetWordMap, lettersWordMap);

        //now we will look for the character that we can print less times
        //this chacater will determine the number of times we can print the target
        //word
        for (Map.Entry<Character, Integer> resultCountKV : result.entrySet()) {
            if(resultCountKV.getValue()<timesCanBePrinted){
                timesCanBePrinted = resultCountKV.getValue();
            }
        }


        return timesCanBePrinted;
    }

    /**
     * 
     * create the map containing the number of times we can
     * print a given character from the target word, with 
     * the current input
     * 
     * @param targetWordMap
     * @param lettersWordMap
     * @return a map containing containing the number of times we can
     * print a given character 
     */
    private static Map<Character, Integer> createMapWithNumberOfTimesWeCanUseEachCharacter(Map<Character, Integer> targetWordMap,
            Map<Character, Integer> lettersWordMap) {
        Map<Character, Integer> result= new HashMap<>();

        for (Map.Entry<Character, Integer> neededLetterCount : targetWordMap.entrySet()) {
            int totalTimesWeCanUseThisCharacter = 0;
            if(lettersWordMap.containsKey(neededLetterCount.getKey())){
                totalTimesWeCanUseThisCharacter = lettersWordMap.get(neededLetterCount.getKey())/neededLetterCount.getValue();
            }
            result.put(neededLetterCount.getKey(), totalTimesWeCanUseThisCharacter);
        }

        return result;
    }


        /**
         * initializes targetWordMap
         * so for hello for example our map will be like this
         *  {h:1,e:1,l:2,o:1} 
         * 
         * @param targetWord
         * @param targetWordMap
         */
    private static void initializeMapWithCharacterCount(String targetWord, Map<Character, Integer> targetWordMap) {
        for(int i = 0;i<targetWord.length();i++){
            if(targetWordMap.containsKey(targetWord.charAt(i))){
                targetWordMap.put(targetWord.charAt(i),targetWordMap.get(targetWord.charAt(i))+1);
            }
            else{
                targetWordMap.put(targetWord.charAt(i),1);
            }
        }
    }