我想打印出来的字符'hello'可以从给定的字符输入中打印出来。你可以建议我做错了吗,因为这段代码没有通过所有测试用例。
int fromDegrees = getResources().getInteger(R.integer.from_degrees);
int toDegrees = getResources().getInteger(R.integer.to_degrees);
我怎么能重构这段代码?
答案 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);
}
}
}