不开辟新的用于字符交换的临时空间实现字符串逆序

原创 2018年04月16日 11:16:19

注意逆序和逆序输出是两个概念。

若只是逆序输出则有很多种方法,最简单的就是,利用C语言中的字符指针。先将指针通过++移到末尾,再--往前移动同时打印输出。

下面主要讨论如何实现逆序

分析:对一个数据进行某种操作,然后进行这种操作的逆操作可以还原到本身。所以实现方法是有多种的。以二进制操作速度最快。这里采用C中的指针概念。

#include <stdio.h>
#include <string.h>
void reverse(char *s)
{
      int i = 0;

      int len = strlen(s);

      int j = len-1;

      while(i < j)
      {

            s[i] ^= s[j] ^= s[i] ^= s[j];
            i++;
            j--;
      }
} 
int main(void)
{

      char str[] = "abcd";

      printf("%s\n",str);

      reverse(str);

      printf("%s\n",str);

      return 0;

}

代码解释,其中的位运算使用了^=相当于

            s[i] = s[i]^s[j];

            s[j] = s[i]^s[j];

            s[i] = s[i]^s[j];

这里^是异或运算符。解释如下

参与运算的两个值,如果两个相应位相同,则结果为0,否则为1。即:0^0=0, 1^0=1,0^1=1, 1^1=0

比如:

int x=7,y=8;   

x=x^y;  

y=x^y;  

x=x^y;   

结果x=8,y=7;

就如同

int x=7,y=8;   

x=x+y;    

y=x-y;    

x=x-y;

实际原理就是数字A异或B两次,就得到A。而B被A异或两次,就得到B。

顺便提一下一个常见错误,在java中实现时,有些人认为以下也实现了需求,但其忽视了String类的不可变性。

public class StringReverseWithoutExtraSpace {
	public static String reverse(String s) {  
	    
		  char[] str = s.toCharArray();  
		    
		  int begin = 0;  
		  int end = s.length() - 1;  
		  while (begin < end) {  
		   str[begin] = (char) (str[begin] ^ str[end]);  
		   str[end] = (char) (str[begin] ^ str[end]);  
		   str[begin] = (char) (str[end] ^ str[begin]);  
		   begin++;  
		   end--;  
		  } 
		  System.out.println(str);//这里实际上打印的是字符数组
		  return new String(str); //若要把逆序结果保留则必须new一个新的字符串对象。因为String具有不可变性。
		 } 
	public static void main(String[] args) {
		String str = "abcd";
		System.out.println(str);
		reverse(str);
		System.out.println(str);
	}
}
打印结果
abcd
dcba

abcd

贴上toCharArray源码:

    
/**
     * Converts this string to a new character array.
     *
     * @return  a newly allocated character array whose length is the length
     *          of this string and whose contents are initialized to contain
     *          the character sequence represented by this string.
     */
    public char[] toCharArray() {
        // Cannot use Arrays.copyOf because of class initialization order issues
        char result[] = new char[value.length];
        System.arraycopy(value, 0, result, 0, value.length);
        return result;
    }

可以发现实际上创建了新空间即使字符数组。

面试:不开辟用于交换数据的临时空间,如何完成字符串的逆序

/********************************************************** 题目:不开辟用于交换数据的临时空间,如何完成字符串的逆序 ***********...
  • shihui512
  • shihui512
  • 2013-04-19 17:12:16
  • 1395

字符串逆序(重新申请空间和不用)

#include #include #include #include using namespace std; char* Reverse(char* s) { //将q指向字符串最后...
  • Zacheus
  • Zacheus
  • 2017-04-15 11:16:04
  • 172

不开辟用于交换数据的临时空间,完成字符串的逆序

  • n70joey
  • n70joey
  • 2009-11-22 16:38:00
  • 2610

链表反转不开辟新空间

看了很多都不全面,这里贴一个自己测试的完整例子,亲测有效 #include using namespace std; struct ListNode { int value; ListNo...
  • forever1dreamsxx
  • forever1dreamsxx
  • 2015-02-27 17:57:30
  • 863

不开辟新空间反转单链表(递归版本)

写的还是很坑的,今天状态奇差 ListNode* ReverseList(ListNode* pHead, ListNode*& pNewHead ) { if ( NULL == pHead )...
  • ssopp24
  • ssopp24
  • 2017-07-09 17:52:52
  • 455

不用临时的变量 交换两个数的两种方法

就地交换两个数是比较经典而且基础的算法之一。 我们要交换两个数字,通常的做法就创建一个中间变量,然后进行循环赋值,比如说下面的代码: void Switch(int* p1, int* p2) {...
  • a253664942
  • a253664942
  • 2015-05-09 16:47:42
  • 2725

在不申请新内存空间条件下交换两个数的值

只是觉得这个问题很好玩,在此记录一下:1. 使用异或运算int a=2,b=4;//此时a的二进制为‘010’,b的二进制为‘100’下面使用编程语言中的‘^’,即异或操作符来完成异或运算,如果a、b...
  • No_Endless
  • No_Endless
  • 2017-03-16 21:02:52
  • 767

new delete 开辟空间和释放空间

  • hutao1101175783
  • hutao1101175783
  • 2014-04-07 20:56:56
  • 732

交换两个变量而不用另外开辟空间。

面试官问:“如何交换两个变量而不用另外开辟空间。”(前提是在嵌入式系统中资源很宝贵).答是使用位操作如下:void swap(int a,int b) {     a=a^b;     b=b^a; ...
  • robinshaw
  • robinshaw
  • 2005-01-28 14:40:00
  • 1620

对一道“写一个算法实现字符串逆序存储,要求不另设串存储空间.”题目的总结!

题目:写一个算法实现字符串逆序存储,要求不另设串存储空间. 针对这一题目给出自己的代码: #include #include /* By LYG */ void rev1(char...
  • lovethinkpad
  • lovethinkpad
  • 2011-11-15 15:23:58
  • 1279
收藏助手
不良信息举报
您举报文章:不开辟新的用于字符交换的临时空间实现字符串逆序
举报原因:
原因补充:

(最多只允许输入30个字)