面試題:將字符串反轉(zhuǎn)的8種方法,你能想到幾種?
面試中,經(jīng)常會遇到這樣的問題,給定字符串“abc123”,你能夠想到幾種方式將該字符串進(jìn)行反轉(zhuǎn),得到“321cba”?
本文就帶大家展示幾種常見的字符串反轉(zhuǎn)的方法。
準(zhǔn)備知識
在學(xué)習(xí)字符串反轉(zhuǎn)的方法之前,先了解幾個背景知識點(diǎn):
String類被final修飾,是不可變的; String類并未提供reverse()方法,但StringBuilder/StringBuffer提供了reverse()方法; StringBuilder沒有toCharArray()方法,但String有toCharArray()方法。 String提供了charAt方法,可以獲得指定索引位置的char值。
字符串轉(zhuǎn)換為字節(jié)數(shù)組
通過getBytes()方法將字符串轉(zhuǎn)換為byte[]數(shù)組?;舅悸罚簞?chuàng)建一個臨時數(shù)組,數(shù)組長度與字符串長度一樣;倒序遍歷通過字符串獲得的字節(jié)數(shù)組,存放到臨時數(shù)組中。最后將數(shù)組轉(zhuǎn)換為String字符串。
@Test
public void bytesReverse() {
String input = "GeeksforGeeks";
byte[] strAsByteArray = input.getBytes();
byte[] result = new byte[strAsByteArray.length];
// 倒序存儲字字節(jié)數(shù)組中的內(nèi)容到臨時字節(jié)數(shù)組中
for (int i = 0; i < strAsByteArray.length; i++) {
result[i] = strAsByteArray[strAsByteArray.length - i - 1];
}
System.out.println(new String(result));
}
這種方式的缺點(diǎn)也很明顯,當(dāng)字符串為中文、日韓等語言時,反轉(zhuǎn)之后基本都是無意義的亂碼了。
通過StringBuilder的reverse()方法
String字符串沒有reverse()方法,因此可以將字符串構(gòu)建為StringBuilder或StringBuffer,利用StringBuilder的reverse()方法來進(jìn)行字符串的反轉(zhuǎn)。
@Test
public void stringBuilderReverse(){
StringBuilder sb = new StringBuilder("程序新視界");
System.out.println(sb.reverse().toString());
}
StringBuilder的reverse()方法對中文也能夠很好的進(jìn)行反轉(zhuǎn)。StringBuffer的使用與StringBuilder一致,不再贅述。
字符串轉(zhuǎn)換為char數(shù)組
首先轉(zhuǎn)換字符串為char數(shù)組,然后倒序打印或拼接char中的數(shù)據(jù)即可。
@Test
public void string2CharReverse(){
String input = "程序新視界";
char[] try1 = input.toCharArray();
for (int i = try1.length - 1; i >= 0; i--) {
System.out.print(try1[i]);
}
}
上面的方式是直接倒序打印,針對獲得的char數(shù)組拼接新字符串還可以通過雙向指針的方式將char數(shù)組中的字符直接互換位置。
@Test
public void string2CharChangeReverse(){
String input = "程序新視界";
char[] tempArray = input.toCharArray();
int right = tempArray.length - 1;
for (int left = 0; left < right; left++, right--) {
// 左右值進(jìn)行交換
char temp = tempArray[left];
tempArray[left] = tempArray[right];
tempArray[right] = temp;
}
for (char c : tempArray) {
System.out.print(c);
}
}
交換的算法很簡單,指定左右指針的起始位置分別為0和length-1,然后進(jìn)行左右位置的交換。完成交換之后left加一,right減一,再次交換,直到不再滿足left小于right的條件。
當(dāng)獲得char數(shù)組之后,還可以利用List和Collections對字符進(jìn)行反轉(zhuǎn)操作。
@Test
public void string2CharListReverse(){
String input = "程序新視界";
char[] hello = input.toCharArray();
List<Character> trial1 = new ArrayList<>();
for (char c : hello) {
trial1.add(c);
}
Collections.reverse(trial1);
for (Character character : trial1) {
System.out.print(character);
}
}
首先同樣將字符串轉(zhuǎn)換為char數(shù)組,然后將數(shù)組里的每一項(xiàng)都放入List當(dāng)中,通過集合工具類Collections的reverse方法對List進(jìn)行反轉(zhuǎn)。
我們還可以通過棧的先進(jìn)后出特性來對char數(shù)組中的字符進(jìn)行倒序處理:
@Test
public void string2Stack() {
String str = "程序新視界";
Stack<Character> s = new Stack<>();
for(int i = 0;i<str.length();i++) {
// 入棧
s.add(str.charAt(i));
}
StringBuffer sb = new StringBuffer();
for(int i = 0;i<str.length();i++) {
// 出棧
sb.append(s.pop());
}
System.out.println(sb);
}
通過charAt方法
String提供了charAt方法,可以用來檢索特定索引下的字符。charAt()方法返回指定索引位置的char值。索引范圍為0~length()-1,chartAt()中的括號只能傳int類型的參數(shù)。
@Test
public void string2CharAt() {
String str = "程序新視界";
for (int i = str.length() - 1; i >= 0; i--) {
System.out.print(str.charAt(i));
}
}
利用遞歸
通過遞歸的方式來達(dá)到字符串的反轉(zhuǎn):
//遞歸
public static String reverse5(String str) {
int len = str.length();
if (len <= 1) {
return str;
}
String left = str.substring(0, len / 2);
String right = str.substring(len / 2, len);
return reverse5(right) + reverse5(left);
}
小結(jié)
上面總結(jié)了8種字符串翻轉(zhuǎn)的方法,但并未完全覆蓋,比如還可以通過Apache commons-lang3中提供的StringUtils.reverse方法進(jìn)行字符串的反轉(zhuǎn)等。
面試中出這道題最主要考慮的就是你的知識面及活學(xué)活用的程度。同時,你可能已經(jīng)看到一些算法和數(shù)據(jù)結(jié)構(gòu)的身影在里面。
往期推薦
如果你覺得這篇文章不錯,那么,下篇通常會更好。添加微信好友,可備注“加群”(微信號:zhuan2quan)。
和花一輩子都看不清的人,
注定是截然不同的搬磚生涯。



