在一个字符串内移动字符

9
String newStr;

public RandomCuriosity(String input){
    newStr = input;
}

public void shiftChars(){
    char[] oldChar = newStr.toCharArray();
    char[] newChar = new char[oldChar.length];
    newChar[0] = oldChar[oldChar.length-1];
    for(int i = 1; i < oldChar.length; i++){
        newChar[i] = oldChar[i-1];
    }
    newStr = String.valueOf(newChar);
}

我创建了一个方法,将字符向前移动一个位置。例如,输入可能是:
输入:Stackoverflow 输出:wStackoverflo 我的操作方式是改变字符串实例。将该字符串转换为 char 数组(称为 oldChar),将 oldChar 的最后一个索引指定为 my new Char 数组的第一个索引,并创建一个 for 循环,将 oldChar 的第一个索引作为新的 Char 数组的第二个索引,以此类推。最后,我将 char 数组转换回字符串。
我感觉我做了太多事情来完成一些非常简单的东西。有没有更有效的方法来完成这样的任务?
编辑:感谢伟大的答案!

你的程序的时间和空间复杂度是多少? - Sotirios Delimanolis
我一点头绪也没有,不过我认为它相当高。 - theGreenCabbage
@Cruncher substringдҢүз”Ёй‡ҚиҢҢзљ„жһ„йЂ е‡Ңж•°пәЊиҮӨжһ„йЂ е‡Ңж•°жҺӨ受偏移量和и®Ұж•°пәЊе№¶дҢүз”ЁArrays.copyOfRange()иҺ·еЏ–字符数组的е‰Үжњ¬гЂ‚ - Sotirios Delimanolis
1
关于术语的说明:您并没有突变字符串的实例。您创建了一个新的字符串,其值类似但不同。字符串是不可变的。 - Sinkingpoint
很好的发现。你说得对。如果字符串是可变的,我就不必做我所做的一切了 =) - theGreenCabbage
显示剩余4条评论
7个回答

20
newStr = newStr.charAt(newStr.length() - 1) + newStr.substring(0, newStr.length() - 1);

哇。这是一个强大的一行代码。所以让我弄清楚。你把最后一个索引视为字符,而在最后一个索引之前的字符作为完整的字符串? - theGreenCabbage
是的。但如果您认为更清晰,也可以使用newStr.substring(newStr.length() - 1)作为第一个操作数。 - JB Nizet
这是一个非常漂亮的解决方案,也是对内置Java方法的巧妙运用。谢谢JB。 - theGreenCabbage
@SotiriosDelimanolis:我认为没问题。O(3n)虽然是O(n)。无论如何,除非字符串真的很大,否则优化这样一个简单任务的性能不应该是你尝试去优化的东西。 - JB Nizet
1
只需要更正代码行。第二个 newStr.length 缺少括号 ()。正确的写法应该是:newStr = newStr.charAt(newStr.length() - 1) + newStr.substring(0, (newStr.length() - 1)); - Caco
显示剩余3条评论

1
你可以让生活更简单:

public static void main (String[] args) throws java.lang.Exception {
    String input = "Stackoverflow";
    for(int i = 0; i < s.length(); i++){
        input = shift(input);
        System.out.println(input);
    }
}

public static String shift(String s) {
    return s.charAt(s.length()-1)+s.substring(0, s.length()-1);
}

输出:

wStackoverflo
owStackoverfl
lowStackoverf
flowStackover
rflowStackove
erflowStackov
verflowStacko
overflowStack
koverflowStac
ckoverflowSta
ackoverflowSt
tackoverflowS
Stackoverflow

0
你可以使用 System.arrayCopy
char[] oldChar = newStr.toCharArray();
char[] newChar = new char[oldChar.length];
newChar[0] = oldChar[oldChar.length - 1];
System.arrayCopy(oldChar, 0, newChar, 1, oldChar.length - 1);

0
你可以使用 StringBuilder。
StringBuilder strb = new StringBuilder();
strb.append(oldChar[oldChar.length-1]).append(oldchar.substring(0, oldChar.length-1));
newStr = strb.toString();

0

试试这个。。

        String old = "String";
        char first = old.charAt(old.length()-1);
        String newString = first+old.substring(0,old.length()-1);
        System.out.println(newString);

0

另一种解决方案,但不使用循环,用于左移和右移:

public static String cyclicLeftShift(String s, int n){ //'n' is the number of characters to shift left
        n = n%s.length();
        return s.substring(n) + s.substring(0, n);
    }
      
public static String cyclicRightShift(String s, int n){ //'n' is the number of characters to shift right
        n = n%s.length();
        return  s.substring(s.length() - n , s.length()) + s.substring(0, s.length() - n);
    }

-1

使用Java,您可以通过O(n)将其向前移动,其中n是要向前移动的字符数,空间为o(1)

public static String shiftChars(String s , int times) {
    String temp = s;
    for (int i = 0; i < times ; i++) {
        temp =  temp.charAt(temp.length()-1)+temp.substring(0, temp.length()-1);
    }
    return temp;
}

你的解决方案与 JB Nizet 接受的答案 相同 - Scratte
不要太在意。实际上,我只是想分享一下我如何使用这段代码解决我的问题,感谢您对代码的关注 ^_^ - lio
您的回答可能会被删除。想法是发布不同的答案。 - Scratte

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