0

我想知道是否可以在将辅音附加到 StringBuilder 变量的正确方法上获得一些帮助。

就目前而言,它成功地找到并计算了在一个句子中找到的元音的数量,但是,我在创建一个排除它们的新变量时遇到了麻烦。

    char[] vowels = {'a', 'e', 'i', 'o', 'u'};
    int vowelCount = 0;
    String defParagraph = "This is an example sentence.";
    StringBuilder sbParagraph = new StringBuilder(defParagraph);
    StringBuilder vowParagraph = new StringBuilder("");

    System.out.print("Characters: " + sbParagraph.length());

    for (int i = 0; i < sbParagraph.length(); i++) {
        for (int j = 0; j < vowels.length; j++) {
            if (sbParagraph.toString().toLowerCase().charAt(i) == vowels[j]) {
                vowelCount++;
            }
        }
    }

我试过简单地vowParagraph.append(sbParagraph.charAt(i)在循环中添加 a ,但它在新字符串中给了我相同字符的倍数。我也考虑过复制原始的 StringBuilder 变量并简单地删除字符,但我根本不知道最好的方法来做到这一点。

我不确定我是否应该坚持使用两个循环和一个数组,或者我是否应该简单地制作一个大量的 if/then 条件来检查值。老实说,这似乎是最简单的方法,但也似乎有点过于冗长和低效。

如果有人可以帮助我阐明我的愚蠢,我将不胜感激。这一直让我发疯。

4

5 回答 5

2

这是替代版本,

String regex = "[aeiou]";
Matcher m = Pattern.compile(regex,Pattern.CASE_INSENSITIVE).matcher(defParagraph); 
while (m.find()) {
  vowelCount++;
}
String vowParagraph=defParagraph.replaceAll(regex, "").toLowerCase();  
于 2012-08-17T17:31:25.903 回答
1

您可以像这样更改循环以避免倍数:

for (int i = 0; i < sbParagraph.length(); i++) {
    char c = defParagraph.toLowerCase().charAt(i);
    boolean isVowel = false;
    for (int j = 0; j < vowels.length; j++) {
        if (c == vowels[j]) {
            isVowel = true;
            break;
        }
    }
    if (isVowel) {
        vowelCount++;
    } else {
        vowParagraph.append(c);
    }
}
于 2012-08-17T17:05:53.403 回答
1

你还没有说明你的结果应该是什么?您是否只想计算句子中有多少个元音?或者你想要一个代表唯一元音的字符串?

如果你想要一个包含句子中所有元音的字符串,那么按照你的想法去做。在for(int j...循环中附加元音。您看到倍数的原因是句子中有倍数。(2个i,2个a,5个e)。

编辑:我刚刚注意到您的问题表明您“需要帮助附加consonants到 StringBuilder”。那你为什么还要关心元音呢?

编辑 2:要仅将辅音附加到 Stringbuilder 试试这个

    String defParagraph = "This is an example sentence.";
    StringBuilder sbParagraph = new StringBuilder(defParagraph);
    StringBuilder conPara = new StringBuilder();

    System.out.println("Characters: " + sbParagraph.length());

    for (int i = 0; i < sbParagraph.length(); i++) {
        char c = sbParagraph.toString().toLowerCase().charAt(i);
        if (c == 'a' || c=='e' || c=='i' || c=='o' || c=='u') {
            continue; // Skip this character.
        }
        conPara.append(c);
    }

    System.out.println("conPara: " + conPara);

输出是:

 Characters: 28
 conPara: ths s n xmpl sntnc.

由于这是家庭作业,我将留给您弄清楚如何删除空格。(它们既不是元音也不是辅音)。

于 2012-08-17T17:38:15.853 回答
1

如何避免O(N^2)循环?

Set<Character> vowels = new HashSet<Character>(Arrays.asList('a','e','i','o','u'));  
int vowelCount = 0;
String sbParagraph = "This is an example sentence.";
StringBuilder vowParagraph = new StringBuilder();

System.out.print("Characters: " + sbParagraph.length());

for (int i = 0, len = sbParagraph.length(); i < len; i++) {  
    int theChar = sbParagraph.charAt(i);
    if(vowels.contains(Character.toLowerCase(theChar)){    
        vowelCount++;    
     }  
     else{  
         vowParagraph.append(theChar);
      }  
}  
于 2012-08-17T17:46:12.327 回答
1

这与其他一些答案类似,但对为什么对代码进行更改进行了一些调整和解释。不过,附带说明一下,如果您可以选择正则表达式,请查看 Adi 的答案。他为您提供了另一种解决问题的方法,但是由于这是家庭作业,因此不确定它是否是可行的解决方案。无论如何,有解释(跳到最终产品的底部):

更改您声明开始的内容

int vowelCount = 0;
// All the Strings/StringBuilders can be final since we will never reinstantiate them
final String defParagraph = "This is an example sentence.";
// We'll just make a lowercase version here. That way we don't 
// .toLowerCase() everytime though the loop, and for people that complain
// about trying to optimize - I think it's easier to read too.
final String lowerCaseVersion = defParagraph.toLowerCase();
// Declare the stringBuilder with the size of defParagraph. That is the
// maximum size the vowel-less text could be, and ensures the stringBuilder
// won't overflow it's initial capacity and have to waste time growing.
final StringBuilder newParagraph = new StringBuilder(defParagraph.length());
// Not using the vowel array. We will remove the loop 
// and just || them together - see below
//char[] vowels = {'a', 'e', 'i', 'o', 'u'};
// You didn't need sbParagraph for anything you had (defParagraph works fine).
// Also, you could have just been a regular String since you never changed it.
//StringBuilder sbParagraph = new StringBuilder(defParagraph);
// Don't need vowParagraph since we aren't tracking the actual vowels, just the count
//StringBuilder vowParagraph = new StringBuilder("");

对实际循环的更改

 for (int i = 0; i < lowerCaseVersion.length(); i++) {
  // grab the current character
  char tempChar = lowerCaseVersion.charAt(i);
  if ('a' == tempChar || 'e' == tempChar || 'i' == tempChar 
        || 'o' == tempChar || 'u' == tempChar) {
    // It matched one of the vowels, so count it
    vowelCount ++;
  } else {
    // It didn't match a vowel, so add it the consonants stringBuilder
    // Oh, and append a character from the original, not the lowerCaseVersion
    newParagraph.append(defParagraph.charAt(i));
  }
}

然后一起没有评论:

int vowelCount = 0;
final String defParagraph = "This is an example sentence.";
final String lowerCaseVersion = defParagraph.toLowerCase();
final StringBuilder newParagraph = new StringBuilder(defParagraph.length());

System.out.println("Characters: " + defParagraph.length());

for (int i = 0; i < lowerCaseVersion.length(); i++) {
  char tempChar = lowerCaseVersion.charAt(i);
  if ('a' == tempChar || 'e' == tempChar || 'i' == tempChar 
        || 'o' == tempChar || 'u' == tempChar) {
    vowelCount ++;
  } else {
    newParagraph.append(defParagraph.charAt(i));
  }
}

System.out.println("\tVowel: " + vowelCount);
System.out.println("\tDefPara: " + defParagraph.toString());
System.out.println("\tNewPara: " + newParagraph.toString());

输出如下:

Characters: 28
  Vowels: 9
  DefPara: This is an example sentence.
  NewPara: Ths s n xmpl sntnc.

笔记

  1. 在这种情况下,使用final确实是可选的。我倾向于尽可能使用它,但这可能是个人喜好。这个问题有一些关于何时使用的讨论final,可能值得一试。
于 2012-08-17T19:01:12.073 回答