如何在不使用 toUpperCase 方法的情况下将字符串转换为大写?

6

我是一个Java的初学者,但无法使这段代码正常工作。我的任务是将输入的任何字符串转换为大写字母,但不能使用toUpperCase字符串方法。以下是我的代码:

public String toUpperCase(String str)
{
    for(int i = 0; i < str.length(); i++)
    {
        char a = str.charAt(i);
        a = Character.toUpperCase(a);
        str += Character.toString(a);
    }
return str;
}

1
但是你正在使用 toUpperCase 方法。 - shmosel
3
我猜这个循环会无限执行下去。 - xiaofeng.li
1
@shmosel 在我看来,OP 的意思是 String.toUpperCase - xiaofeng.li
1
如果你需要在实现自己的 toUpperCase 方法时获得“灵感”,为什么不看一下 Java 源代码呢?例如,对于拉丁字符,toUpperCase 方法可以在 CharacterDataLatin1#toUpperCase() 中找到;你可以通过查找 CharacterData 类的具体实现来找到其他类型字符的 toUpperCase() 方法。 - Jason Hoetger
1
这个基本想法肯定是可行的。让它对你不起作用的原因是你正在使用相同的“String”变量作为输入和输出。只需使用两个不同的“String”变量,您就应该能够使其正常工作。 - Dawood ibn Kareem
显示剩余4条评论
6个回答

8
您正在使用 str 作为输入,并输出(因此您的 String 具有无限长度,因为您不断添加字符)。您可以使用 static,因为您没有使用实例状态。而且,您可能会使用 for-each 循环。最后,添加另一个 String,或者更好地使用 StringBuilder,如下所示:
public static String toUpperCase(String str) {
    StringBuilder sb = new StringBuilder();
    for (char ch : str.toCharArray()) {
        sb.append(Character.toUpperCase(ch));
    }
    return sb.toString();
}

既然您已经调用了 str.toCharArray(),那么将该数组中的字符替换为它们的大写等效项,然后执行 return new String(array) 是否更好呢? - Andreas
@Andreas 当然有不止一种方法可以做到这一点。Zack在你发表评论的时候在一个答案中发布了这个。 - Elliott Frisch

5
以下是一种方法,但它不考虑英语以外的任何字符(没有 变音符号,也没有其他语言的 a-z 后面的字符)。
public String toUpperCase(String str) {
    char[] chars = str.toCharArray();

    for (int i=0; i<chars.length; i++) {
        char c = chars[i];
        if ('a' <= c && c <= 'z') {
            chars[i] = (char) (c - 'a' + 'A');
        }
    }

    return new String(chars);
}

2

我知道你们学校可能不允许使用 StringBuilder,而且如果你也不能使用数组的话,这是另一种原始的方法,你的学校可能会接受:

public static String toUpperCase(String s){
    String str = "";
    for(int x=0; x<s.length(); x++){
        char ch = s.charAt(x);
        if(ch >= 'a' && ch <= 'z')
            str += "" + (char)(ch - 32);
        else
            str += "" + ch; 
    }
    return str;
}

测试:

System.out.println(toUpperCase("aAbBcC"));

输出:

AABBCC

为什么不允许使用 StringBuilder?此外,那段代码隐式地使用了 StringBuilder,只是非常、非常慢而已。 - Andreas
通过我过去与来自不同学校的学生的经验,到目前为止,即使“string+=”是一种糟糕的方法,他们的学校也没有使用“StringBuilder”。 - user3437460

1

由于无法使用 toUpperCase() 方法,您可以使用 ASCII表 通过减去32将小写字母转换为大写字母。

'a' = 97,'A' = 65
'b' = 98,'B' = 66
...
'z' = 122,'Z' = 90

public static int DIFF = 'a' - 'A'; // 32

public static String toUpperCase(String str) {
    StringBuilder sb = new StringBuilder();
    for (char c : str.toCharArray()) {
        if (Character.isLowerCase(c)) {
            sb.append(String.valueOf((char)(c - DIFF)));
        } else {
            sb.append(c);
        }
    }
    return sb.toString();
}

1
你错误地假设输入字符串仅仅包含小写字母。 - Andreas
@Andreas 确实。已修复。 - κροκς
1
如果你不能使用 toUpperCase()(而且你确实不能),难道你不认为 isLowerCase() 也同样被禁用了吗? - Andreas
@Andreas,由于OP没有对isLowerCase()做出任何限制,所以不需要。此外,其他答案使用的条件ch >= 'a' && ch <= 'z'假设输入仅使用英文字母表。Character.isLowerCase()适用于UTF-16。 - κροκς
正确,但是你的代码对UTF-16无效。toUpperCase("ā")返回á,因为大写字母并不总是比它们的小写等价物少32个码点。 - Andreas

1

try it:

public static String toUpperCase(String str) {
        String result = "";
        for (int i = 0; i < str.length(); i++) {
            int v = str.charAt(i);
            if (v > 96 && v < 123) {
                v -= 32;
            }
            result+=(char)v;

        }
        return result;
    }

1

各位,拜托了,Java 8已经发布多年了!

/**
 * Converts an all-lowercase String to
 * uppercase. Retains only spaces, any
 * other characters will be lost.
 */
public static String toUpperCase(String s) {
    int diff = 'a' - 'A'; // 32

    return s.chars()
            .filter(c -> c >= 'a' && c <= 'z' || c == ' ')
            .mapToObj(c -> String.valueOf((char) (c - (diff))))
            .collect(Collectors.joining());
}

有趣的事实是,在工作中我们必须使用Java 6进行开发,因为需要考虑兼容性问题。 - BlackCat
@BlackCat 我完全理解。我真的希望Java更新是强制/无缝的,这样我们就不必处理任何兼容性问题了。 - Jacob G.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接