那么有朋友大概会使用类似下面这样的循环方法

 

面是实现字符串反转的四种方法:

转自:

栈和队列_栈

数组 链表 树 适用于数据库应用中作数据记录
int[] a =new int[10];
a[1]=100;
int b=a[1];

public static class Utils
    {
        /// <summary>
        /// 普通方法——字节数组转字符串,最容易想到
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string BytesToString(byte[] input)
        {
            StringBuilder sb = new StringBuilder();
            foreach (byte b in input)
            {
                sb.Append(b.ToString("X2"));
            }
            return sb.ToString();
        }

方法一:

图片 1            static string Reverse1(string original)
图片 2图片 3            ...{
图片 4                char[] arr = original.ToCharArray();
图片 5                Array.Reverse(arr);
图片 6                return new string(arr);
图片 7            }
图片 8
图片 9            static string Revease21(string original)
图片 10图片 11            ...{
图片 12                int length = original.Length;
图片 13                char[] arr = new char[length];
图片 14                for (int i = 0; i < (length & (~3)); i += 4)
图片 15图片 16                ...{
图片 17                    arr[i] = original[length - i - 1];
图片 18                    arr[i+1] = original[length - i - 2];
图片 19                    arr[i+2] = original[length - i - 3];
图片 20                    arr[i+3] = original[length - i - 4];
图片 21                }
图片 22                for (int i = length & (~3); i < length; i++)
图片 23图片 24                ...{
图片 25                    arr[i] = original[length - i - 1];
图片 26                }
图片 27                return new string(arr);
图片 28            }
图片 29
图片 30            static string Revease22(string original)
图片 31图片 32            ...{
图片 33                int length = original.Length;
图片 34                char[] arr = new char[length];
图片 35                for (int i = 0; i < length; i++)
图片 36图片 37                ...{
图片 38                    arr[i] = original[length - i - 1];
图片 39                }
图片 40                return new string(arr);
图片 41            }
图片 42
图片 43            static string Revease3(string original)
图片 44图片 45            ...{
图片 46                int length = original.Length;
图片 47                StringBuilder sb = new StringBuilder(length);
图片 48                for (int i = length-1; i >= 0; i--)
图片 49                sb.Append(original[i]);
图片 50                return sb.ToString();
图片 51            }

 

栈和队列 1.通常情况作为程序员的工具来运用

        2.受限访问
        3.更加抽象(主要通过接口进行定义)

栈就是一组记录,表现形式为先进后出

        /// <summary>
        /// 高效的字节数组转字符串
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string BytesToStringH(byte[] input)
        {
            int len = input.Length;
            char[] chars = new char[len * 2];
            for (int i = 0; i < len; i++)
            {
                chars[i * 2] = IntToChar(input[i] >> 4);
                chars[i * 2 + 1] = IntToChar(input[i] & 15);
            }
            return new string(chars);
        }
        /// <summary>
        /// 使用指针效率最高
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static unsafe string BytesToStringS(byte[] input)
        {
            int len = input.Length;
            char[] chars = new char[len * 2];
            fixed (char* lchars = chars)
            {
                fixed (byte* linput = input)
                {
                    char* pchar = lchars;
                    byte* pbyte = linput;
                    for (int i = 0; i < len; i++)
                    {
                        *pchar = IntToChar(*pbyte >> 4);
                        pchar++;
                        *pchar = IntToChar(*pbyte & 15);
                        pchar++;
                        pbyte++;
                    }
                }
            }
            return new string(chars);
        }

public static string Reverse(string name)
{
     if (String.IsNullOrEmpty(name))
       {
           throw new Exception("字符串不能为空!");
       }
    StringBuilder sb = new StringBuilder(name.Length);
    for (int i = name.Length-1; i >= 0; i--)
     {
        sb.Append(name[i]);
    }
        return sb.ToString();
}

 Revease1()中对char[]进行了两次赋值(ToCharArray()和Array.Revease),所以我有想到了Revease2和Revease3()两种方法,下面是对这四种方法进行简单性能测试的代码:

1. 使用Array.Reverse方法

表示栈的代码

public class StackX{
private long[] stackArray;
private int maxSize;
private int top;//指向最顶层的位置
public StackX(int s){
maxSize=s;
stackArray=new long[maxSize];
top=-1;//因为第一个放进去的数据应该放在数组的0里面,初始没有的话 就给-1
}
//添加数据,永远往上添加
public void push(long j){
stackArray[++top]=j;
}
//查看并删除
public long pop(){
return stackArray[top--];
}
//查看
public long peek(){
return stackArray[top];
}
public boolean isEmpty(){
return top==-1;//如果top==-1则是空的,因为我们初始设置的
}
public boolean isFull(){
return top==(maxSize-1);
}
}

Public class StackApp{
Public static void main(String[]args){
StackX theStack=new StackX(10);
theStack.push(20);
theStack.push(40);
theStack.push(60);
theStack.push(80);
while(theStack.isEmpty()){
long value=theStack.pop();
System.out.print(value+””);
}
System.out.println();
System.ut.println(“theStack.isEmpty=”+theStack.isEmpty());
}
}

        /// <summary>
        /// 普通方法——字符串转字节数组,最容易想到
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static byte[] StringToBytes(string input)
        {
            int len = input.Length;
            if (len % 2 != 0)
            {
                throw new Exception("输入的字符串长度有误,必须是偶数。");
            }
            byte[] bytes = new byte[len / 2];
            for (int i = 0; i < len / 2; i++)
            {
                if (!byte.TryParse(input.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber, null, out bytes[i]))
                {
                    throw new Exception(string.Format("在位置{0}处的字符无法转换为16进制字节", i * 2 + 1));
                }
            }
            return bytes;
        }

 

图片 52   static void Main(string[] args)
图片 53图片 54            ...{
图片 55                string testString = "测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转测试字符串反转";
图片 56                DateTime start = DateTime.Now;
图片 57                for (int i = 0; i < 3000000; i++)
图片 58图片 59                ...{
图片 60                    string s = Reverse1(testString);
图片 61                }
图片 62                DateTime end = DateTime.Now;
图片 63                Console.WriteLine("1 :  "+(end - start));
图片 64
图片 65                start = DateTime.Now;
图片 66                for (int i = 0; i < 3000000; i++)
图片 67图片 68                ...{
图片 69                    string s = Revease21(testString);
图片 70                }
图片 71                end = DateTime.Now;
图片 72                Console.WriteLine("21:  " + (end - start));
图片 73
图片 74                start = DateTime.Now;
图片 75                for (int i = 0; i < 3000000; i++)
图片 76图片 77                ...{
图片 78                    string s = Revease22(testString);
图片 79                }
图片 80                end = DateTime.Now;
图片 81                Console.WriteLine("22:  " + (end - start));
图片 82
图片 83                start = DateTime.Now;
图片 84                for (int i = 0; i < 3000000; i++)
图片 85图片 86                ...{
图片 87                    string s = Revease3(testString);
图片 88                }
图片 89                end = DateTime.Now;
图片 90                Console.WriteLine("3 :  " + (end - start));
图片 91
图片 92                Console.ReadLine();
图片 93            }

对于字符串反转,我们可以使用.NET类库自带的Array.Reverse方法

Java实例1:单词逆序

public class StackX {
private int maxSize;
private char[] stackArray;//栈数组
private int top;//指针
public StackX(int max) {
maxSize=max;
stackArray=new char[maxSize];
top=-1;//top开始的时候位置是0 所以=-1
}
public void push(char j) {
stackArray[++top]=j;//先让top递增一个再赋值
}
public char pop() {
return stackArray[top--];//弹出
}
public char peek() {
return stackArray[top];//查找
}
public boolean isEmpty() {
//栈是否为空
return top==-1;
}
}

public class Reverser {
private String input;//通过构造函数传过来的input
private String output;
public Reverser(String in) {
input=in;
}
public String doRev() {//反转
int stackSize=input.length();
StackX theStack=new StackX(stackSize);//创建一个栈
for(int j=0;j<input.length();j++) {
char ch=input.charAt(j);//拿出来字符串中指定的字符
theStack.push(ch);
}
output="";
while(!theStack.isEmpty()) {
char c=theStack.pop();
output=output+c;

    }
    return output;
}

}

import java.io.*;
public class ReverseApp {
public static void main(String[]args ) throws IOException{//抛出异常
String input,output;
while(true) {
System.out.println("Enter a String:");
System.out.flush();//刷新一下
input=getString();
if(input.equals(""))break;
Reverser theReverser=new Reverser(input);
output=theReverser.doRev();
System.out.println("Reversed:"+output);
StringBuilder sb=new StringBuilder("中华人民共和国");
System.out.println("StringBuilder reverse:"+sb.reverse());
}
}
public static String getString() throws IOException{
InputStreamReader isr=new InputStreamReader(System.in);//输入流的读取器
BufferedReader br=new BufferedReader(isr);//带缓存的读取器
String s=br.readLine();
return s;
}
}

        /// <summary>
        /// 高效的字符串转字节数组
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static byte[] StringToBytesH(string input)
        {
            int len = input.Length;
            if (len % 2 != 0)
            {
                throw new Exception("输入的字符串长度有误,必须是偶数。");
            }
            byte[] bytes = new byte[len / 2];
            for (int i = 0; i < len / 2; i++)
            {
                try
                {
                    bytes[i] = (byte)((CharToInt(input[2 * i]) << 4) + CharToInt(input[2 * i + 1]));
                }
                catch (Exception e)
                {
                    throw new Exception(string.Format("在位置{0}处的字符无法转换为16进制字节,原始信息为:{1}", i * 2 + 1, e.Message));
                }
            }
            return bytes;
        }

方法二:.NET3.5以上

测试结果是Revease1()代码最简洁,运行速度也最快,Revease21()和Revease22()其次,Revease3()最慢。可见.net framework中实现的ToCharArray()和Array.Revease()效率还是蛮高的^_^

public static string ReverseByArray(string original)
{
char[] c = original.ToCharArray();
Array.Reverse(c);
return new string(c);
}

Java实例2:分隔符匹配

public class StackX {
private int maxSize;
private char[] stackArray;//栈数组
private int top;//指针
public StackX(int max) {
maxSize=max;
stackArray=new char[maxSize];
top=-1;//top开始的时候位置是0 所以=-1
}
public void push(char j) {
stackArray[++top]=j;//先让top递增一个再赋值
}
public char pop() {
return stackArray[top--];//弹出
}
public char peek() {
return stackArray[top];//查找
}
public boolean isEmpty() {
//栈是否为空
return top==-1;
}
}

public class BracketChecker {
private String input;
public BracketChecker(String in) {
input=in;
}
//写一个检查的方法
public void check() {
int stackSize=input.length();
StackX theStack=new StackX(stackSize);
//a{b(c[d]e)f} {([ ])}
for(int j=0;j<input.length();j++) {
char ch=input.charAt(j);
switch(ch) {
case '{':
case '(':
case '[':
theStack.push(ch);//放入栈里
break;
case '}':
case ')':
case ']':
if(theStack.isEmpty()) {
char chx=theStack.pop();
if((ch=='}'&& chx!='{')||(ch==']'&& chx!='[')||(ch==')'&& chx!='(')
) {
System.out.println("Error:"+ch+"at"+j);
}
}
else {
System.out.println("Error:"+ch+"at"+j);
}
break;
default:
break;
}
}
if(!theStack.isEmpty())System.out.println("Error:missing right delimiter.");
}
}

import java.io.*;

public class BracketApp {
public static void main(String[]args) throws IOException {
String input;
while(true) {
System.out.println("Enter string containing delimiters:");
System.out.flush();
input=getString();
if(input.equals(""))break;
BracketChecker theChecker=new BracketChecker(input);
theChecker.check();
}
}
public static String getString() throws IOException{
InputStreamReader isr=new InputStreamReader(System.in);//输入流的读取器
BufferedReader br=new BufferedReader(isr);//带缓存的读取器
String s=br.readLine();
return s;
}
}

        /// <summary>
        /// 使用指针效率最高
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static unsafe byte[] StringToBytesS(string input)
        {
            int len = input.Length;
            if (len % 2 != 0)
            {
                throw new Exception("输入的字符串长度有误,必须是偶数。");
            }
            byte[] bytes = new byte[len / 2];
            fixed (byte* lbytes = bytes)
            {
                fixed (char* linput = input)
                {
                    byte* pbyte = lbytes;
                    char* pchar = linput;
                    for (int i = 0; i < len / 2; i++)
                    {
                        try
                        {
                            *pbyte = (byte)(CharToInt(*pchar) << 4);
                            pchar++;
                            *pbyte += (byte)CharToInt(*pchar);
                            pchar++;
                            pbyte++;
                        }
                        catch (Exception e)
                        {
                            throw new Exception(string.Format("在位置{0}处的字符无法转换为16进制字节,原始信息为:{1}", i * 2 + 1, e.Message));
                        }
                    }
                }
            }
            return bytes;
        }
        /// <summary>
        /// 输入一个16进制字符,返回小于16的正整数
        /// </summary>
        /// <param name="input">16进制字符</param>
        /// <returns>小于16的正整数</returns>
        private static int CharToInt(char input)
        {
            if (input >= '0' && input <= '9')
            {
                return input - '0';
            }
            else if (input >= 'a' && input <= 'z')
            {
                return input - 'a' + 10;
            }
            else if (input >= 'A' && input <= 'Z')
            {
                return input - 'A' + 10;
            }
            throw new Exception(string.Format("字符({0})超出16进制范围,无法转换", input));
        }

public static string Reverse(string name)
{
     char[] reverse = name.Reverse().ToArray();

但还有个奇怪的问题,就是Debug版本中的Revease1()和Revease21()运行起来要比Release版本中的要快,而Revease22()和Revease3()就比较正常。按说Release时做了更多的优化工作,运行起来更快才对,迷惑ing...,下面是测试结果:

2. 使用字符缓存

        /// <summary>
        /// 输入一个小于16的正整数,返回对应的16进制字符。
        /// </summary>
        /// <param name="input">小于16的正整数</param>
        /// <returns>16进制字符</returns>
        private static char IntToChar(int input)
        {
            if (input >= 0 && input <= 9)
            {
                return (char)(input + '0');
            }
            else if (input >= 10 && input <= 15)
            {
                return (char)(input - 10 + 'A');
            }
            throw new Exception(string.Format("输入({0})超出16进制范围,无法转换", input));
        }
    }

     return new string(reverse);
}

Debug:

在面试或笔试中,往往要求不用任何类库方法,那么有朋友大概会使用类似下面这样的循环方法

 

1 :  00:00:03.4375000
21:  00:00:06.1250000
22:  00:00:09.9687500
3 :  00:01:05.5468750

public static string ReverseByCharBuffer(this string original)
{
char[] c = original.ToCharArray();
int l = original.Length;
char[] o = new char[l];
for (int i = 0; i < l ; i++)
{
o[i] = c[l - i - 1];
}
return new string(o);
}

本文由必威发布于必威-编程,转载请注明出处:那么有朋友大概会使用类似下面这样的循环方法

TAG标签:
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。