2

问题:给定一个字符串作为输入,将所有大写字母移动到字符串的末尾。例子:

move("Hello World")="ello orldHW"

问题是:我的代码并没有停止,ello orldHW而是继续

ello orldHW // Expected output   
ello orldWH // What I am actually getting

代码:

public class MoveUppercaseChars {   
    static String testcase1 = "Hello World";

    public static void main(String args[]){
       MoveUppercaseChars testInstance = new MoveUppercaseChars();
       String result = testInstance.move(testcase1);
       System.out.println("Result : "+result);
    }

    public String move(String str){
       int len = str.length();
       char ch;
       for(int i=0; i<len; i++) {
          ch = str.charAt(i);
          if(((int)ch >= 65) && ((int)ch <= 90)) {
             str = str.substring(0, i) + str.substring(i+1, len) + str.charAt(i);
          }         
       }
       return str;
   }    
}
4

8 回答 8

4

分别存储小写字符和大写字符,然后返回两者的连接:

public class MoveUppercaseChars {   

static String testcase1 = "Hello World";

public static void main(String args[]){
    MoveUppercaseChars testInstance = new MoveUppercaseChars();
    String result = testInstance.move(testcase1);
    System.out.println("Result : "+result);
}

public String move(String str){
    int len = str.length();
    String low = "";
    String cap = "";
    char ch;
    for(int i=0; i<len; i++)
    {
        ch = str.charAt(i);
        if(((int)ch >= 65) && ((int)ch <= 90))
        {
            cap  += ch;
        }   
        else {
            low += ch;
        }
    }
    return low + cap;
}   
}
于 2013-08-22T17:16:47.870 回答
4

我会使用辅助字符串缓冲区以正确的顺序存储大写字母:甚至小写字母,因此您创建的字符串实例更少。

public String move(String str){
    char ch;
    int len = str.length();
    // we initialize the buffers with the size so they won't have to be increased
    StringBuffer sbUpperCase = new StringBuffer(len+1);
    StringBuffer sbLowerCase = new StringBuffer(len+1);

    for(int i=0; i<len; i++)
    {
        ch = str.charAt(i);

        //if it is an upperCase letter (but only of the normal ones
        if(Character.isUpperCase(ch))
        {
            sbUpperCase.append(ch);
        }   else {
            sbLowerCase.append(ch);
        }        
    }
    return sbLowerCase.append(sbUpperCase).toString();
} 

使用 Eclipse IDE 进行编辑以获得更好的格式设置并使用 Character.isUpperCase(ch) 检查是否为大写。关于为什么在字符串之间使用 StringBuffer 而不是 + 运算符很有用,请查看以下问题:Why to use StringBuffer in Java instead of the string concatenation operator

于 2013-08-22T17:17:57.730 回答
3

最简单和最小的代码解决方案:

public String move(String str) {
    return s.replaceAll("[A-Z]+", "") + s.replaceAll("[^A-Z]+", "");
}

基于非正则表达式的解决方案:

使用StringBuilder这个算法可以变得非常简单:

public String move(String str){
    StringBuilder sb = new StringBuilder(str);
    int d=0;
    for(int i=0; i<str.length(); i++) {
        int ch = str.charAt(i);
        if(ch >= 65 && ch <= 90) {
            sb.deleteCharAt(i-d++).append((char)ch);
        }           
    }
    return sb.toString();
}  

与多次操作不可变 String 对象相比,这也将更加有效。

于 2013-08-22T17:32:19.380 回答
2

将循环更改为从字符串的末尾开始,然后向后工作。此外,使用 char[] 数组,它会比在循环的每次迭代中构建一个新字符串更快。就像是:

编辑:这可能是最有效的方法:

    char[] input = str.toCharArray();
    int c = input.length; // cursor to start at
    int ip = input.length - 1; // insertion point of next UP character.
    while (c > 0) {
        c--;
        if (Character.isUpperCase(input[c])) {
            char tmp = input[c];
            System.arraycopy(input, c + 1, input, c, ip - c);
            input[ip] = tmp;
            ip--;
        }
    }
    return new String(input);

编辑:以下循环不是最有效的......所以将这个代码示例向下移动。

boolean gotUC=true; // do we have upper-case letters, initialize to true
char[] input = str.toCharArray();
int len = input.length;
while (len > 1 && gotUC) {
    len--;
    int c = len;
    while (c > 0 && !Character.isUpperCase(input[c])) {
       c--;
    }
    if (c >= 0) {
        // move the UC Char to before previous UCase letters....
        char tmp = input[c];
        System.arraycopy(input, c + 1, input, c, len - c);
        input[len] = tmp;
    } else {
        gotUC = false;
    }
}
return new String(input);
于 2013-08-22T17:22:23.490 回答
1

问题是这个词H处理了两次,在第二次处理期间它被推到最后

您可能希望跟踪处理的总大写单词,以便它们不会再次被处理

此外,您可以使用Character.isUpperCase(ch)检查字符是否为大写

public class Test {

    public static void main(String[] args){
        System.out.println(move("Hello World"));
    }

    public static int getUpperCaseLetters(String str) {
        int r = 0;
        for(char c : str.toCharArray()) {
            if(Character.isUpperCase(c)) {
                r++;
            }
        }
        return r;
    }

    public static String move(String str){
        int len = str.length();
        char ch;
        int totalUppercase = getUpperCaseLetters(str);
        int processed = 0;
        for(int i=0; i<len && processed < totalUppercase; i++)
        {
            ch = str.charAt(i);
            if(Character.isUpperCase(ch))
            {
                str = str.substring(0, i) + str.substring(i+1, len) + str.charAt(i);                
                System.out.println(str);
                processed++;
            }           
        }
        return str;
    }   
}
于 2013-08-22T17:17:45.117 回答
1
public String move(String str) {
    int todo = str.length();
    int i = 0;
    while (i < todo)
    {
        char c = str.charAt(i);
        if (c >= 65 && c <= 90) {
            str = str.substring(0, i) + str.substring(i + 1, str.length())
                    + str.charAt(i);
            --todo;
            --i;
        }
        ++i;
    }
    return str;
}

这无需额外的 String var 即可工作。基本思路:如果在字符串末尾放一个大写字符,就知道不需要去到字符串末尾。因此限制最初是 str.length() ,后来递减。

此外,如果您找到匹配项,则必须再次检查该确切位置(因此 --i)。使用您的代码或其他代码片段尝试“你好世界”。

于 2013-08-22T18:06:57.900 回答
0

我会循环输入字符串两次,首先复制出小写字母,然后复制出大写字母。

public static String move(String str) {
    char[] input = str.toCharArray();
    char[] result = new char[input.length];
    int index = 0;

    for (char current : input)
        if (!Character.isUpperCase(current))
            result[index++] = current;

    for (char current : input)
        if (Character.isUpperCase(current))
            result[index++] = current;

    return new String(result);
}
于 2013-08-22T18:31:16.003 回答
0
public class MoveUpperCaseToEnd {

public static void main(String[] args) {
    String string = "SoftwareEngineer";
    String result = moveUpperCase(string);
    System.out.println(result);

}

public static String moveUpperCase(String s) {
    String lowerCase = "";
    String upperCase = "";
    for (int i = 0; i < s.length(); i++) {
        char ch = s.charAt(i);
        if (ch >= 'A' && ch <= 'Z') {
            upperCase += ch;
        } else {
            lowerCase += ch;
        }
    }
    return lowerCase + upperCase;
}

}

于 2019-07-08T17:02:48.280 回答