剑指Offer 面试题4 替换空格

                                                                     剑指Offer 面试题4 替换空格

      本文参考《剑指offer 名企面试官精讲典型编程题》面试题4。

      感谢原书作者:何海涛。

      题目4:请实现一个函数,把字符串中的每个空格替换成"%20"。例如:输入"hello world.",则输出"hello%20world."。

      在网络编程中,如果URL参数中含有特殊字符,如空格,'#'等,可能导致服务端无法获得正确的参数值。我们需要将特殊符号转换为服务器可以识别的字符。转换规则为在'%'后面跟上ASCII码的两位十六进制。空格可以被替换为"%20",'#'可以被替换为"%23"。

      时间复杂度为O(n)的解法:

      可以先遍历一次字符串,统计出字符串中的空格总数,并由此计算出替换之后的字符串总长度。每替换一个空格,长度增加2。替换后的字符串长度等于原来的长度加上空格数乘以2。

      准备两个指针P1,P2从后往前开始复制替换。P1指向原字符串末尾,P2指向替换之后的字符串末尾。接下来我们向前移动指针P1,逐步将它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。碰到第一个空格后,P1向前移动一格,P2之前插入"%20",同时把P2向前移动3格。当P1和P2指向同一个位置,表明所有空格替换完毕。

      以下为操作示意图:

                              

                                                    注:图中阴影区域表示被移动的字符。

         我以Java为编程语言实现上述思想:

package array;

/**
 * @author WuPing
 * @version 2016年4月8日 上午11:05:59
 */

public class ReplaceBlank {

    public static void replaceBlank(char strings[], int length) {
	// length为字符数组string的总容量
	if (strings != null && length > 0) {
	    int originalLength = 0; // 字符数组实际长度
	    int numberOfBlank = 0; // 字符数组中的空格数
	    int i = 0;
	    while (strings[i] != '\0') {
		++originalLength;

		if (strings[i] == ' ')
		    ++numberOfBlank;

		++i;
	    }

	    // newLength为把空格替换成'%20'之后的长度
	    int newLength = originalLength + numberOfBlank * 2;
	    if (newLength > length)
		return;

	    int indexOfOriginal = originalLength; // 字符数组起始扫描索引
	    int indexOfNew = newLength; // 替换空格后的字符数组起始扫描索引
	    while (indexOfOriginal >= 0 && indexOfNew > indexOfOriginal) {
		// 从后向前扫描,遇到空格则替换成'%20',否则直接复制字符
		if (strings[indexOfOriginal] == ' ') {
		    strings[indexOfNew--] = '0';
		    strings[indexOfNew--] = '2';
		    strings[indexOfNew--] = '%';
		} else {
		    strings[indexOfNew--] = strings[indexOfOriginal];
		}

		--indexOfOriginal;
	    }
	}
    }

    //空格在字符串中间
    public static void Test1(int length) {
	char[] test1Strings = new char[length];
	test1Strings[0] = 'h';
	test1Strings[1] = 'e';
	test1Strings[2] = 'l';
	test1Strings[3] = 'l';
	test1Strings[4] = 'o';
	test1Strings[5] = ' ';
	test1Strings[6] = 'w';
	test1Strings[7] = 'o';
	test1Strings[8] = 'r';
	test1Strings[9] = 'l';
	test1Strings[10] = 'd';
	test1Strings[11] = '\0'; // 模拟字符串结束符

	System.out.println("Test1 begin: ");
	System.out.print("替换空格前的字符数组:");
	for (int i = 0; i < test1Strings.length; i++) {
	    if (test1Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test1Strings[i]);
	}
	System.out.println();

	replaceBlank(test1Strings, length);

	System.out.print("替换空格后的字符数组:");
	for (int i = 0; i < test1Strings.length; i++) {
	    if (test1Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test1Strings[i]);
	}
	System.out.println();
    }

    //空格在字符串开头
    public static void Test2(int length) {
	char[] test2Strings = new char[length];
	test2Strings[0] = ' ';
	test2Strings[1] = 'h';
	test2Strings[2] = 'e';
	test2Strings[3] = 'l';
	test2Strings[4] = 'l';
	test2Strings[5] = 'o';
	test2Strings[6] = 'w';
	test2Strings[7] = 'o';
	test2Strings[8] = 'r';
	test2Strings[9] = 'l';
	test2Strings[10] = 'd';
	test2Strings[11] = '\0';  // 模拟字符串结束符

	System.out.println("Test2 begin: ");
	System.out.print("替换空格前的字符数组:");
	for (int i = 0; i < test2Strings.length; i++) {
	    if (test2Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test2Strings[i]);
	}
	System.out.println();

	replaceBlank(test2Strings, length);

	System.out.print("替换空格后的字符数组:");
	for (int i = 0; i < test2Strings.length; i++) {
	    if (test2Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test2Strings[i]);
	}
	System.out.println();
    }
    
    //空格在字符串末尾
    public static void Test3(int length) {
	char[] test3Strings = new char[length];
	test3Strings[0] = 'h';
	test3Strings[1] = 'e';
	test3Strings[2] = 'l';
	test3Strings[3] = 'l';
	test3Strings[4] = 'o';
	test3Strings[5] = 'w';
	test3Strings[6] = 'o';
	test3Strings[7] = 'r';
	test3Strings[8] = 'l';
	test3Strings[9] = 'd';
	test3Strings[10] = ' ';
	test3Strings[11] = '\0';  // 模拟字符串结束符

	System.out.println("Test3 begin: ");
	System.out.print("替换空格前的字符数组:");
	for (int i = 0; i < test3Strings.length; i++) {
	    if (test3Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test3Strings[i]);
	}
	System.out.println();

	replaceBlank(test3Strings, length);

	System.out.print("替换空格后的字符数组:");
	for (int i = 0; i < test3Strings.length; i++) {
	    if (test3Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test3Strings[i]);
	}
	System.out.println();
    }
    
    //字符串中有连续两个空格
    public static void Test4(int length) {
	char[] test4Strings = new char[length];
	test4Strings[0] = 'h';
	test4Strings[1] = 'e';
	test4Strings[2] = 'l';
	test4Strings[3] = 'l';
	test4Strings[4] = 'o';
	test4Strings[5] = ' ';
	test4Strings[6] = ' ';
	test4Strings[7] = 'w';
	test4Strings[8] = 'o';
	test4Strings[9] = 'r';
	test4Strings[10] = 'l';
	test4Strings[11] = 'd';
	test4Strings[12] = '\0';  // 模拟字符串结束符

	System.out.println("Test4 begin: ");
	System.out.print("替换空格前的字符数组:");
	for (int i = 0; i < test4Strings.length; i++) {
	    if (test4Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test4Strings[i]);
	}
	System.out.println();

	replaceBlank(test4Strings, length);

	System.out.print("替换空格后的字符数组:");
	for (int i = 0; i < test4Strings.length; i++) {
	    if (test4Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test4Strings[i]);
	}
	System.out.println();
    }
    
    //字符数组为null
    public static void Test5() {
	System.out.print("Test5 begin: ");
	replaceBlank(null, 0);
	System.out.println("passed!");
    }
    
    //字符串为空串
    public static void Test6(int length) {
	char[] test6Strings = new char[length];
	test6Strings[0] = '\0';  // 模拟字符串结束符

	System.out.println("Test6 begin: ");
	System.out.print("替换空格前的字符数组:");
	for (int i = 0; i < test6Strings.length; i++) {
	    if (test6Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test6Strings[i]);
	}
	System.out.println();

	replaceBlank(test6Strings, length);

	System.out.print("替换空格后的字符数组:");
	for (int i = 0; i < test6Strings.length; i++) {
	    if (test6Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test6Strings[i]);
	}
	System.out.println();
    }
    
    //字符串为一个空格
    public static void Test7(int length) {
	char[] test7Strings = new char[length];
	test7Strings[0] = ' ';  
	test7Strings[1] = '\0';  // 模拟字符串结束符

	System.out.println("Test7 begin: ");
	System.out.print("替换空格前的字符数组:");
	for (int i = 0; i < test7Strings.length; i++) {
	    if (test7Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test7Strings[i]);
	}
	System.out.println();

	replaceBlank(test7Strings, length);

	System.out.print("替换空格后的字符数组:");
	for (int i = 0; i < test7Strings.length; i++) {
	    if (test7Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test7Strings[i]);
	}
	System.out.println();
    }
    
    //字符串中没有空格
    public static void Test8(int length) {
	char[] test8Strings = new char[length];
	test8Strings[0] = 'h';
	test8Strings[1] = 'e';
	test8Strings[2] = 'l';
	test8Strings[3] = 'l';
	test8Strings[4] = 'o';
	test8Strings[5] = 'w';
	test8Strings[6] = 'o';
	test8Strings[7] = 'r';
	test8Strings[8] = 'l';
	test8Strings[9] = 'd';
	test8Strings[10] = '\0'; // 模拟字符串结束符

	System.out.println("Test8 begin: ");
	System.out.print("替换空格前的字符数组:");
	for (int i = 0; i < test8Strings.length; i++) {
	    if (test8Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test8Strings[i]);
	}
	System.out.println();

	replaceBlank(test8Strings, length);

	System.out.print("替换空格后的字符数组:");
	for (int i = 0; i < test8Strings.length; i++) {
	    if (test8Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test8Strings[i]);
	}
	System.out.println();
    }
    
    //字符串中全是空格
    public static void Test9(int length) {
	char[] test9Strings = new char[length];
	test9Strings[0] = ' ';
	test9Strings[1] = ' ';
	test9Strings[2] = ' ';
	test9Strings[3] = ' ';
	test9Strings[4] = '\0'; // 模拟字符串结束符

	System.out.println("Test9 begin: ");
	System.out.print("替换空格前的字符数组:");
	for (int i = 0; i < test9Strings.length; i++) {
	    if (test9Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test9Strings[i]);
	}
	System.out.println();

	replaceBlank(test9Strings, length);

	System.out.print("替换空格后的字符数组:");
	for (int i = 0; i < test9Strings.length; i++) {
	    if (test9Strings[i] == '\0') {
		break;
	    }
	    System.out.print(test9Strings[i]);
	}
	System.out.println();
    }
    
    public static void main(String[] args) {
	int length = 100;
	Test1(length);
	Test2(length);
	Test3(length);
	Test4(length);
	Test5();
	Test6(length);
	Test7(length);
	Test8(length);
	Test9(length);
    }

}
           程序运行结果如下图:
                                              

你可能感兴趣的:(字符串,面试题,空格替换)