问题:给定一个字符串作为输入,将所有字母表以大写字母移动到字符串的末尾。例如:
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;
}
}
答案 0 :(得分: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;
}
}
答案 1 :(得分: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
答案 2 :(得分:2)
将循环更改为从字符串末尾开始,然后向后工作。另外,使用char []数组,它会比在循环的每次迭代中构建一个新的String更快。类似的东西:
编辑:这可能是最有效的方式:
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);
答案 3 :(得分:2)
最简单&amp;最小的代码解决方案:
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对象相比,这也会更有效。
答案 4 :(得分: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;
}
}
答案 5 :(得分: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。基本理念: 如果将大写字母char放在字符串的末尾,则表示您不需要转到字符串的末尾。因此,限制最初是str.length(),后来递减。
此外,如果您找到匹配项,则必须再次检查确切位置(因此--i)。尝试使用您的代码或其他代码片段“HEllo WOrld”。
答案 6 :(得分: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);
}
答案 7 :(得分: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;
}
}