面试中,经常会遇到这样的问题,给定字符串“abc123”,你能够想到几种方式将该字符串进行反转,得到“321cba”?
本文就带大家展示几种常见的字符串反转的方法。
准备知识
在学习字符串反转的方法之前,先了解几个背景知识点:
- String类被final修饰,是不可变的;
- String类并未提供reverse()方法,但StringBuilder/StringBuffer提供了reverse()方法;
- StringBuilder没有toCharArray()方法,但String有toCharArray()方法。
- String提供了charAt方法,可以获得指定索引位置的char值。
字符串转换为字节数组
通过getBytes()方法将字符串转换为byte[]数组。基本思路:创建一个临时数组,数组长度与字符串长度一样;倒序遍历通过字符串获得的字节数组,存放到临时数组中。最后将数组转换为String字符串。
@Test public void bytesReverse() { String input = "GeeksforGeeks"; byte[] strAsByteArray = input.getBytes(); byte[] result = new byte[strAsByteArray.length]; // 倒序存储字字节数组中的内容到临时字节数组中 for (int i = 0; i < strAsByteArray.length; i++) { result[i] = strAsByteArray[strAsByteArray.length - i - 1]; } System.out.println(new String(result)); }
这种方式的缺点也很明显,当字符串为中文、日韩等语言时,反转之后基本都是无意义的乱码了。
通过StringBuilder的reverse()方法
String字符串没有reverse()方法,因此可以将字符串构建为StringBuilder或StringBuffer,利用StringBuilder的reverse()方法来进行字符串的反转。
@Test public void stringBuilderReverse(){ StringBuilder sb = new StringBuilder("程序新视界"); System.out.println(sb.reverse().toString()); }
StringBuilder的reverse()方法对中文也能够很好的进行反转。StringBuffer的使用与StringBuilder一致,不再赘述。
字符串转换为char数组
首先转换字符串为char数组,然后倒序打印或拼接char中的数据即可。
@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数组拼接新字符串还可以通过双向指针的方式将char数组中的字符直接互换位置。
@Test public void string2CharChangeReverse(){ String input = "程序新视界"; char[] tempArray = input.toCharArray(); int right = tempArray.length - 1; for (int left = 0; left < right; left++, right--) { // 左右值进行交换 char temp = tempArray[left]; tempArray[left] = tempArray[right]; tempArray[right] = temp; } for (char c : tempArray) { System.out.print(c); } }
交换的算法很简单,指定左右指针的起始位置分别为0和length-1,然后进行左右位置的交换。完成交换之后left加一,right减一,再次交换,直到不再满足left小于right的条件。
当获得char数组之后,还可以利用List和Collections对字符进行反转操作。
@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); } }
首先同样将字符串转换为char数组,然后将数组里的每一项都放入List当中,通过集合工具类Collections的reverse方法对List进行反转。
我们还可以通过栈的先进后出特性来对char数组中的字符进行倒序处理:
@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类型的参数。
@Test public void string2CharAt() { String str = "程序新视界"; for (int i = str.length() - 1; i >= 0; i--) { System.out.print(str.charAt(i)); } }
利用递归
通过递归的方式来达到字符串的反转:
//递归 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); }
小结
上面总结了8种字符串翻转的方法,但并未完全覆盖,比如还可以通过Apache commons-lang3中提供的StringUtils.reverse方法进行字符串的反转等。
面试中出这道题最主要考虑的就是你的知识面及活学活用的程度。同时,你可能已经看到一些算法和数据结构的身影在里面。