zoukankan      html  css  js  c++  java
  • 使用位运算、值交换等方式反转java字符串-共四种方法

    在本文中,我们将向您展示几种在Java中将String类型的字符串字母倒序的几种方法。

    • StringBuilder(str).reverse()
    • char[]循环与值交换
    • byte循环与值交换
    • apache-commons-lang3

    如果是为了进行开发,请选择StringBuilder(str).reverse()API。出于学习的目的,我们可以研究char[]byte方法,其中涉及到值互换和移位运算技术,这些技术对于了解StringBuilder(str).reverse()API黑匣子背后原理非常有帮助。

    1. StringBuilder(str).reverse()

    在Java中,我们可以使用StringBuilder(str).reverse()使字符串字母倒序。

    public class ReverseString1 {
    
        public static void main(String[] args) {
    
            String str = "Reverse a String in Java";
    
            StringBuilder sb = new StringBuilder(str).reverse();
    
            System.out.println(sb.toString());
    
        }
    }
    

    输出结果

    avaJ ni gnirtS a esreveR
    

    2.char[]

    首先,我们将字符串转换为char数组,并逐个循环char数组,并使用temp变量交换值。

    public class ReverseString2 {
    
        public static void main(String[] args) {
    
            String str = "Hello World";
            System.out.println(reverse(str));         //  dlroW olleH
    
        }
    
        public static String reverse(String input) {
    
            if (input == null || input.length() < 0)
                throw new IllegalArgumentException("Please provide an input!");
    
            char[] result = input.toCharArray();
    
            int startIndex = 0;
            int endIndex = result.length - 1;
            char temp;
    
            for (; endIndex > startIndex; startIndex++, endIndex--) {
                temp = result[startIndex];
                result[startIndex] = result[endIndex];
                result[endIndex] = temp;
            }
    
            return new String(result);
        }
    
    }
    

    上面的算法需要5个循环(长度/ 2)来使字符串倒序“ Hello World”。

    ------------------------------------
    H  e  l  l  o     W  o  r  l  d
    ------------------------------------
    0  1  2  3  4  5  6  7  8  9  10
    ------------------------------------
    
    Loop #1 - Swap index 0 <-> index 10
    ------------------------------------
    {d}  e  l  l  o     W  o  r  l  {H}
    ------------------------------------
    {0}  1  2  3  4  5  6  7  8  9  {10}
    ------------------------------------
    
    Loop #2 - Swap index 1 <-> index 9
    ------------------------------------
    d  {l}  l  l  o     W  o  r  {e}  H
    ------------------------------------
    0  {1}  2  3  4  5  6  7  8  {9}  10
    ------------------------------------
    
    Loop #3 - Swap index 2 <-> index 8
    ------------------------------------
    d  l  {r}  l  o     W  o  {l}  e  H
    ------------------------------------
    0  1  {2}  3  4  5  6  7  {8}  9  10
    ------------------------------------
    
    Loop #4 - Swap index 3 <-> index 7
    ------------------------------------
    d  l  r  {o}  o     W  {l}  l  e  H
    ------------------------------------
    0  1  2  {3}  4  5  6  {7}  8  9  10
    ------------------------------------
    
    Loop #5 - Swap index 4 <-> index 6
    ------------------------------------
    d  l  r  o  {W}     {o}  l  l  e  H
    ------------------------------------
    0  1  2  3  {4}  5  {6}  7  8  9  10
    ------------------------------------
    

    3. Byte[] – StringBuilder(str).reverse(str)

    以下代码段类似于StringBuilder(str).reverse()的内部实现(UTF16内容除外)。

    import java.nio.charset.StandardCharsets;
    
    public class ReverseString3 {
    
        public static void main(String[] args) {
    
            String str = "Hello World";
            System.out.println(reverse(str));
    
        }
    
        public static String reverse(String input) {
    
            if (input == null || input.length() < 0)
                throw new IllegalArgumentException("Please provide an input!");
    
            byte[] val = input.getBytes(StandardCharsets.UTF_8);
            int length = val.length - 1;
    
            for (int start = (length - 1) >> 1; start >= 0; start--) {
                int end = length - start;
                byte temp = val[start];
                val[start] = val[end];
                val[end] = temp;
    
                // debugging
                //System.out.println(String.format("start=%s, end=%s", start, end));
            }
    
            return new String(val);
        }
    
    }
    

    最令人困惑的部分是右移运算符(length - 1) >> 1,这是什么意思?查看下面的8位示例,您可以找到规律吗?

    System.out.println(10>>1);  //  10 -> 5
    0000 1010   = 10
    0000 0101|0 = 10 >> 1 = 5
    
    System.out.println(4>>1);   //  4 -> 2
    0000 0100   = 4
    0000 0010|0 = 4 >> 1 = 2
    
    System.out.println(100>>1); //  100 -> 50
    0110 0100   = 100
    00110 010|0 = 100 >> 1 = 50
    
    System.out.println(7>>1);   //  7 -> 3
    0000 0111   = 7
    0000 0011|1 = 7 >> 1 = 3
    

    对于数字,每右移1位,金额将减少该值的一半并四舍五入。这(length - 1) >> 1试图找出字符串的中间点。

    number >> 1 = round_down(number/2) or Math.flooa(number/2)
    

    值交换从内部开始,然后扩展到外部。

    for (int start = (length - 1) >> 1; start >= 0; start--) {
        int end = length - start;
        byte temp = val[start];
        val[start] = val[end];
        val[end] = temp;
    }
    

    上面的算法图示如下:

    ------------------------------------
    H  e  l  l  o     W  o  r  l  d
    ------------------------------------
    0  1  2  3  4  5  6  7  8  9  10
    ------------------------------------
    
    Loop #1 - Swap index 4 <-> index 6
    ------------------------------------
    H  e  l  l  {W}     {o}  o  r  l  d
    ------------------------------------
    0  1  2  3  {4}  5  {6}  7  8  9  10
    ------------------------------------
    
    Loop #2 - Swap index 3 <-> index 7
    ------------------------------------
    H  e  l  {o}  W     o  {l}  r  l  d
    ------------------------------------
    0  1  2  {3}  4  5  6  {7}  8  9  10
    ------------------------------------
    
    Loop #3 - Swap index 2 <-> index 8
    ------------------------------------
    H  e  {r}  o  W     o  l  {l}  l  d
    ------------------------------------
    0  1  {2}  3  4  5  6  7  {8}  9  10
    ------------------------------------
    
    Loop #4 - Swap index 1 <-> index 9
    ------------------------------------
    H  {l}  r  o  W     o  l  l  {e}  d
    ------------------------------------
    0  {1}  2  3  4  5  6  7  8  {9}  10
    ------------------------------------
    
    Loop #5 - Swap index 0 <-> index 10
    ------------------------------------
    {d}  l  r  o  W     o  l  l  e  {H}
    ------------------------------------
    {0}  1  2  3  4  5  6  7  8  9  {10}
    ------------------------------------
    

    4. Apache commons-lang3

    对于Apache commons-lang3库,我们可以使用StringUtils.reverse反转字符串和StringUtils.reverseDelimited反转单词。

    pom.xml

    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.10</version>
    </dependency>
    
    import org.apache.commons.lang3.StringUtils;
    
    public class ReverseString3 {
    
        public static void main(String[] args) {
    
            System.out.println(StringUtils.reverse("Hello World Java"));                // reverse string
    
            System.out.println(StringUtils.reverseDelimited("Hello World Java", ' '));  // reverse words
    
        }
    }
    

    输出结果

    avaJ dlroW olleH
    
    Java World Hello
    

    查看其源代码,Apache-commons-lang3其实是使用new StringBuilder(str).reverse()来反转字符串。

    package org.apache.commons.lang3;
    
      public class StringUtils {
    
      public static String reverse(final String str) {
          if (str == null) {
              return null;
          }
          return new StringBuilder(str).reverse().toString();
      }
    
      //...
    }
    

    欢迎关注我的博客,里面有很多精品合集

    • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

    觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

  • 相关阅读:
    uc浏览器开发版
    探索.NET中的事件机制
    “多态枚举”数值如何判断?
    关于“程序集与命名空间”
    AutoResetEvent和ManualResetEvent的异同
    C# 获取DOS命令的返回值
    自定义控件——自绘
    关于using……的一些探讨
    XmlDocument操作xml类
    使用Trigger实现Cascading的功能
  • 原文地址:https://www.cnblogs.com/zimug/p/13297068.html
Copyright © 2011-2022 走看看