【问题标题】:Subroutine Returns all Capitals on a String Paramter, Should only be first letter子程序返回字符串参数上的所有大写字母,只能是第一个字母
【发布时间】:2015-12-16 22:33:45
【问题描述】:

我的一个问题集要求我创建一个子例程,它将一个字符串变量作为参数并返回相同的字符串,除了每个单词的首字母大写。文中的例子使用了教授专门设计的非标准类。我不想这样做,因为我认为通过标准课程学习比看看还有什么更有意义。我遇到的问题是我的子程序是返回一个全部大写的字符串。这是我的代码:

import java.util.Scanner;

public class Capitalize {

static String capitalizeString(String x) {

    String completedConversion = "";

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

        if (i == 0) {
            char ch = x.charAt(i);
            ch = Character.toUpperCase(ch);
            completedConversion = completedConversion + ch;
            i++;
        }

        if (Character.isLetter(i - 1)) {

            char ch = x.charAt(i);
            completedConversion = completedConversion + ch;
         }

        else {

            char ch = x.charAt(i);
            ch = Character.toUpperCase(ch);
            completedConversion = completedConversion + ch;
        }

    }

    return completedConversion;

} // End of subroutine

我还没有添加任何评论等,但应该很简单。

已解决:使用 Keammoort 的答案

public class Capitalize {

    static String capitalizeString(String x) {

        String completedConversion = "";

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

            if (i == 0) {
                char ch = x.charAt(i);
                ch = Character.toUpperCase(ch);
                completedConversion = completedConversion + ch;
            }

            else if (!Character.isWhitespace(x.charAt(i - 1))) {

                char ch = x.charAt(i);
                completedConversion = completedConversion + ch;

            }

            else {

                char ch = x.charAt(i);
                ch = Character.toUpperCase(ch);
                completedConversion = completedConversion + ch;
            }

        }

return completedConversion;

【问题讨论】:

  • 我最初确实有一个“if, else if, else”,但暂时删除了它。
  • else convert everything to uppercase?您还应该对 Java 中的String 连接进行一些研究,并考虑改用StringBuilder。事实上,你的整个循环是不敬的,因为你只想影响第一个字符
  • 它们是教科书问题集(教科书实际上是免费在线提供的),没有额外的学分
  • 这里已经回答了同样的问题stackoverflow.com/questions/1892765/…
  • 你为什么把java.util.Scanner放在开头?

标签: java string subroutine capitalization


【解决方案1】:

识别问题

这部分代码会导致问题:

if (Character.isLetter(i - 1)) {
    char ch = x.charAt(i);
    completedConversion = completedConversion + ch;
} else {
    char ch = x.charAt(i);
    ch = Character.toUpperCase(ch);
    completedConversion = completedConversion + ch;
}

首先,当传递的参数转换为字符(使用codePoint)是字母字符时,带有int 类型参数的方法Character.isLetter() 返回true。因此,对于相当多的初始迭代,您将获得false。如果Character.isLetter() 返回false,那么您无论如何都要将字母更改为大写。

获取实际字符

我认为应该有:

if (Character.isLetter(x.charAt(i - 1))) { //added getting character from input String
    char ch = x.charAt(i);
    completedConversion = completedConversion + ch;
} else {
    char ch = x.charAt(i);
    ch = Character.toUpperCase(ch);
    completedConversion = completedConversion + ch;
}

使用 isWhitespace() 代替 isLetter()

更好:使用 isWhitespace() 方法。它将防止数字在单词中的情况(然后数字后的字符也将是大写的)。

if (!Character.isWhitespace(x.charAt(i - 1))) {
    //if previous char is not a whitespace don't change case
    char ch = x.charAt(i);
    completedConversion = completedConversion + ch;
} else {
    //if previous char is a whitespace change to uppercase
    char ch = x.charAt(i);
    ch = Character.toUpperCase(ch);
    completedConversion = completedConversion + ch;
}

然后所有紧跟在空格、制表符等之后的字符都将是大写的。

使用 StringBuilder

将所有这些放在一起并使用 StringBuilder 以避免创建许多临时字符串将是:

static String capitalizeString(String x) {
    StringBuilder completedConversion = new StringBuilder();

    for (int i = 0; i < x.length(); i++) {
        if (i == 0) {
            char ch = x.charAt(i);
            ch = Character.toUpperCase(ch);
            completedConversion.append(ch);
            i++;
        }

        if (!Character.isWhitespace(x.charAt(i - 1))) {
            char ch = x.charAt(i);
            completedConversion.append(ch);
        } else {
            char ch = x.charAt(i);
            ch = Character.toUpperCase(ch);
            completedConversion.append(ch);
        }

    }

    return completedConversion.toString();
}

【讨论】:

  • 这是正确的解决方案,但我的声誉还不够高。不过我会指出:如果我在“获取实际字符”下使用您的解决方案,则生成的字符串将是正确的,除非有标点符号,在这种情况下,后面的字符大写。但是,当我按照您的建议为 .isWhitespace 分出 .isLetter 时,一切正常。我还想说我感谢您编辑了我不正确的代码,而不是提供完全不同的方式来执行任务。这促进了学习过程,我被限制在这组数组中。
  • 实际上,在我刚才所说的基础上,这是我的问题的一部分,人们有时会因为答案已经发布在某个地方而感到害怕。这可能是同一问题的正确解决方案,但如果学生或业余编码人员不知道为什么他们的代码出错,他们不太可能通过切换到他们不理解或不理解的全新解决方案来从错误中吸取教训不要发现自己。
  • @TheArchitect 如果您的声誉不够高,您无法投票,但您可以接受这个答案(点击我的答案旁边的绿色勾号),以便其他可能遇到的人类似的问题会知道这个解决方案解决了它。至于第二条评论,我同意有时理解问题所在比仅仅获得其他解决方案更重要。
【解决方案2】:

应该这样做,我用空格将字符串拆分(这样我就可以知道每个大写的位置)到一个数组中,使用toUpperCase()substring 将数组中的每个字符串大写,然后返回放在一起的字符串再次。

public class Capitalize 
{

    static String capitalizeString(String x) 
    {

        String[] splitString = x.split(" "); // Splits the string.
        x = "";
        for (int i = 0; i < splitString.length; i++)
            if (splitString[i].length() > 1)
                x += splitString.substring(0,1).toUpperCase() + splitString.substring(1) + " ";
            else
                x += splitString.substring(0,1).toUpperCase() + " ";
        return x;
    }
}

【讨论】:

  • 谢谢,我也打算使用拆分,但我们不会在这个问题集中使用数组...应该在我的帖子中添加。
【解决方案3】:

使用这个:

String cap = str.substring(0, 1).toUpperCase() + str.substring(1);

【讨论】:

    【解决方案4】:

    第二个if里面,替换

    Character.isLetter(i - 1)

    Character.isLetter(x.charAt(i - 1))

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-24
      • 1970-01-01
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      相关资源
      最近更新 更多