2015-10-04 71 views
1

我在写一个赋值方法。用Java划分和字符串中的单词

描述:如果一个字符串包含一个包含大写字母的单词,我的方法需要大写整个单词。

所以“你好计算器,我的名字是约翰”将产生“你好计算器,我的名字是约翰”

我的代码:

/*Helper method for capitalizeWords() capitalizes word if necesarry*/ 
private static String capitalizeWord(String s, int position) { 
    int i = position; 
    String word = ""; 
    String testWord = ""; 

    while (s.charAt(i) != ' ' && i < s.length() - 1) { 
     word += s.charAt(i); 
     i++; 
    } 
    word += " "; 
    testWord = word.toLowerCase(); 
    if (!testWord.equals(word)) { 
     word = word.toUpperCase(); 
    } 
    return word; 
} 

public static String capitalizeWords(String s) { 
    StringBuilder newString = new StringBuilder(); 
    if (s.length() == 1) { 
     newString.append(s.charAt(0)); 
     return newString.toString(); 
    } 

    for (int i = 0; i < s.length(); i++) { 
     if (i == 0) { 
      newString.append(capitalizeWord(s, i)); 
     } else if (s.charAt(i) == ' ') { 
      newString.append(capitalizeWord(s, i + 1)); 
     } 
    } 
    return newString.toString(); 
} 

正如你可以看到我的代码是低效的,当运行,跳过字符串的最后一个字符:

HW2.capitalizeWords("Guess what?? There are twenty-sIx letters in the English alphABEt!") 
"GUESS what?? THERE are TWENTY-SIX letters in the ENGLISH ALPHABET " 

我不能想办法解决,而无需手动添加的最后一个字符,这可能将是对这个分配分折换货。我宁愿学习解决这个问题的正确,有效的方法(给出允许的方法),而不是努力想出一个粗略的解决方案。

你们有没有介意给我一些想法?我不能使用substringindexOf

+0

我会看看使用.split方法并提供一个空格作为参数。看到这里:http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String) –

+0

是的开始与分割字符串的字或者字符串.split或一个StringTokenizer。然后,您可以检查每个单词的第一个字符,以决定是否必须将其大写。 – hotzst

+1

@hotzst不一定是第一个,任何角色。 – Tunaki

回答

2

至于跳过最后一个字符,请检查您while循环:

while(s.charAt(i) != ' ' && i <s.length()-1) 
{ 
    word += s.charAt(i); 
    i++; 
} 

你循环,直到s.length()-1但不包括它,所以你会丢失掉一个字符。改为使用s.length()。如果你想使用s.length()-1,那么你需要使用i <= s.length()-1

然后你需要编辑while循环,因为如果你这样离开,你会在调用s.charAt(i)时得到一个异常。

将您的循环更改为while(i < s.length() && s.charAt(i)) - 如果第一部分不是真的,则不会评估第二部分,因此您将避免此错误。

+1

如果你这样做,你会得到一个'StringIndexOutOfBoundsException'。 – Makoto

+0

我刚刚添加,当我看到你的答案:) – helencrump

+0

我以前试过,但收到以下error.java.lang.StringIndexOutOfBoundsException:字符串索引超出范围:67 – JDI

1

你其实很接近。你需要做两个改变。

首先,你在迭代循环中的字符太少。您想要一直到i < s.length(),而不是s.length() - 1

但是,如果您只是进行了更改,那么s.charAt(i)语句会出现问题,因为i将在下一个循环中出界。

要解决,翻转你&&

while (i < s.length() && s.charAt(i) != ' ') { 
    word += s.charAt(i); 
    i++; 
} 

由于&&短路,你会不会评估,如果i >= s.length()第二部分。

+0

谢谢我欣赏它! – JDI

1

您可以简化代码并利用Character中的实用方法(如isWhitespace(char)isUpperCase(char))。我也建议使用for-each loop。然后你可以建立一个单独的单词。喜欢的东西,

public static String capitalizeWords(String s) { 
    StringBuilder sb = new StringBuilder(); 
    StringBuilder word = new StringBuilder(); 
    boolean capital = false; 
    for (char ch : s.toCharArray()) { 
     if (Character.isWhitespace(ch)) { 
      if (word.length() > 0) { 
       sb.append(capital ? word.toString().toUpperCase() : word); 
       word.setLength(0); 
       capital = false; 
      } 
      sb.append(ch); 
      continue; 
     } else if (Character.isUpperCase(ch)) { 
      capital = true; 
     } 
     word.append(ch); 
    } 
    if (word.length() > 0) { 
     sb.append(capital ? word.toString().toUpperCase() : word); 
    } 
    return sb.toString(); 
} 

我与

System.out.println(capitalizeWords("Guess what?? There are twenty-sIx letters " 
    + "in the English alphABEt!")); 
System.out.println(capitalizeWords("hello StackOverFlow, my name is John")); 

测试获得(预期)

GUESS what?? THERE are TWENTY-SIX letters in the ENGLISH ALPHABET! 
hello STACKOVERFLOW, my name is JOHN 
+0

我真的很感谢这个解决方案。不幸的是,我们不允许在循环中使用“继续”。另外,我们不允许使用数组。我的教授似乎认为它是用来补偿设计不佳的循环,但我个人在我的代码中使用过它,从来没有遇到过问题。 – JDI

0

我相信,下面的代码可以帮助您与您的任务。

public String capitalize(String sentence) { 
    String[] words = sentence.split(" "); 
    for (int i = 0; i < words.length; ++i) { 
     String word = words[i]; 
     for (int j = 0; j < word.length(); ++j) { 
      if (Character.isUpperCase(word.charAt(j))) { 
       words[i] = words[i].toUpperCase(); 
       break; 
      } 
     } 
    } 
    StringBuffer result = new StringBuffer(); 
    for (String word : words) { 
     result.append(word).append(" "); 
    } 
    return result.toString(); 
}