Java 计算使用给定输入字符串创建单词的次数

Java 计算使用给定输入字符串创建单词的次数,java,java-8,Java,Java 8,我想打印从给定的字符输入中可以打印单词“hello”的次数。你能指出我做错了什么吗,因为这段代码没有通过所有的测试用例 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+

我想打印从给定的字符输入中可以打印单词“hello”的次数。你能指出我做错了什么吗,因为这段代码没有通过所有的测试用例

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++;}
}

if(h>=1&&e>=1&&l>=2&&o>=1){
    count++;
    h--;
    e--;
    o--;
    l=l-2;
}
System.out.println(count);  
String strInput=br.readLine()//读字符串
整数计数=0;
int h=0,e=0,l=0,o=0;
对于(int i=0;i=1&&e>=1&&l>=2&&o>=1){
计数++;
h--;
e--;
o--;
l=l-2;
}
系统输出打印项次(计数);

还有,我如何重构这段代码?

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);
}
publicstaticvoidmain(字符串[]args){
String strInput=br.readLine();//读取字符串
整数计数=0;
int h=0,e=0,l=0,o=0;
对于(int i=0;i=1)和&(e>=1)和&(l>=2)和&(o>=1)){
计数++;
h--;
e--;
o--;
l=l-2;
}
}
系统输出打印项次(计数);
}

您的代码看起来几乎不错;但它的主要问题是:它的层次很低,因此很难阅读

你看,所有这些计数器和数组访问。。。不太好。而且:您在代码中硬编码了“hello”。如果您的任务是检查一些任意单词,该怎么办

因此,让我们来了解一下如何改进代码

您可以使用
Map
来记住打印一个特定单词所需的字符:

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);
}
String wordToCount=“hello”//或者:来自用户!
Map numberOfRequiredCharsPerChar=新HashMap();
for(chart-charToCount:wordToCount.toCharArray()){
如果(!numberOfRequiredCharsPerChar.ContainesKey(charToCount)){
//未知字符,所以我们需要一个计数器
numberOfRequiredCharsPerChar.put(charToCount,新整数(0));
}
int currentCounter=numberOfRequiredCharsPerChar.get(charToCount);
所需的CharsPerchar.put数(charToCount,currentCounter+1);
}
因此:上面迭代了“first”输入,之后,就像“hello”一样,该映射告诉您需要打印什么:

hx1,e1,llx2,ox1

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

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 ...
int-possibleCounts=0;
字符串InputToCunton=。。。。
Map numberOfUsedCharacters=新HashMap(numberOfRequiredCharsPerChar);
for(char availableChar:inputToCountOn()){
if(numberOfUsedCharacters.containsKey(availableChar)){
int currentCounter=numberOfUsedCharacters.get(availableChar);
电流计数器--;
如果(currentCounter==0){
numberOfUsedCharacters.remove(可用的CHAR);
}否则{
numberOfUsedCharacters.put(availableChar,currentCounter);
}
if(umberOfUsedCharacters.isEmpty()){
//这意味着:我们获取了打印单词所需的所有字符
可能计数++;
//重置我们的“计数器”地图
numberOfUsedCharacters=新HashMap(numberOfRequiredCharsPerChar);
}
}
…现在您只需打印可能的计数。。。

当然,这看起来比您的输入更复杂,但它更灵活。如果您愿意花一些时间为每个活动创建一些辅助方法,您可以用非常可读的方式写下整个过程。

这里有一个通用的重构解决方案来解决您的问题

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

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


因此,使用以下代码,您可以调用

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);
            }
        }
    }
private static int timescanneprint(字符串targetWord,字符串字母){
Map targetWordMap=new HashMap();
Map lettersWordMap=新HashMap();
//初始化targetWordMap
//以hello为例,我们的地图是这样的
//{h:1,e:1,l:2,o:1}
initializeMapWithCharacterCount(targetWord,targetWordMap);
使用CharacterCount(字母、字母和地图)初始化Map;
int timescanbeprint=Integer.MAX_值;
Map result=CreateMapWithNumberOfTimesWeCanUseAchCharacter(TargetTorDorMap,lettersWordMap);
//现在,我们将寻找可以打印较少次数的字符
//这将决定我们可以打印目标的次数
//话
对于(Map.Entry resultCountKV:result.entrySet()){

if(resultCountKV.getValue()这里是另一个选项。关于它的一些注释:
我使用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;
    }
}
import java.util.HashMap;
导入java.util.Map;
公开课考试{
静态字符串word=“hello”;
静态弦纹;
公共静态void main(字符串[]args){
strInput=“hoe4olelltohlemlllhoslelo”//读取字符串
Map charMap=mapNumOfChars();
整数计数=0;
布尔完成=假;
而(!完成){
for(字符c:charMap.keySet()){
如果(!hasTheN