替换空格

11 篇文章 0 订阅
9 篇文章 0 订阅

    来自《剑指offer》面试题4:替换空格。

    牛客网AC地址:http://www.nowcoder.com/books/coding-interviews/4060ac7e3e404ad1a894ef3e17650423?rp=1

    题目:请实现一个函数,将一个字符串中的空格替换成“%20”。例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。

    在牛客网上看到了给出的函数框架为,public String replaceSpace(StringBuffer str) {} ——这样,可以使用StringBuffer的话,题目的难度就减少了。

        关注StringBuffer的两个函数:

        int indexOf(String str, int fromIndex)
              从指定的索引处开始,返回第一次出现的指定子字符串在该字符串中的索引。

if the string argument occurs as a substring within this object, then the index of the first character of the first such substring is returned; if it does not occur as a substring, -1 is returned.

        StringBuffer replace(int start, int end, String str)
              使用给定 String 中的字符替换此序列的子字符串中的字符(参数:start包括,end不包括)

    由此AC的Java代码为

public class Solution {
	public String replaceSpace(StringBuffer str) {
		
		while (str.indexOf(" ") != -1) { // 找到空格出现的地方
			int indexSpace = str.indexOf(" ");
			str.replace(indexSpace, indexSpace + 1, "%20");  // 注意参数:Parameters: start The beginning index, inclusive.  
									 // end The ending index, exclusive.
		}
		
		return str.toString();
	}
}

    测试代码为:
public class Main {
	public static void main(String[] args) {
		Solution testSolution = new Solution();
		System.out.println("Waiting input:");
		Scanner scanner = new Scanner(System.in);
		String val = scanner.nextLine();
		System.out.println("Replace space:" + testSolution.replaceSpace(new StringBuffer(val)));
	}
}
    运行结果:

   


    这里补充,C的思路及代码。时间复杂度为O(n)

    如果从前开始遍历字符串的话,每出现一个空格,就要进行替换,然后替换之后后面的字符串全部后移……这样进行操作的话,时间复杂度是O(n2)。

    如果面试官要求时间复杂度为O(n),该怎么处理呢?

    思路分析:

    最终结果,该字符串长度增加了。由此,我们可以考虑从最终结果入手,指针从最终结果的末尾开始移动。

    首先,先遍历一次字符串,统计出字符串中空格的个数,来计算替换之后字符串的总长度。(替换之后的字符串长度=原来的长度+2*空格数,这里是2*空格数,是因为原来的空格已经占有了一个长度,只需要在原来的基础上再增加两个长度就可以将%20插入进去)

    然后,从字符串的后面开始复制和替换。准备两个指针,P1和P2,P1指向原始字符串的末尾,而P2指向替换之后的字符串的末尾。

         P1向前移动,逐个把它指向的字符复制到P2指向的位置,直到碰到第一个空格为止。

        碰到空格之后,P1向前移动1格,在P2之前插入字符串"%20",由于"%20"的长度为3,所以P2也要向前移动3格。

         P1和P2的不断重复上述操作,直到P1和P2指向同一位置(此时所有的空格已经全部替换了)。

    按照这样的思路,所有的字符都只复制(移动)了一次,由此这个算法的时间复杂度为O(n)。

    这个思路书写的代码为:

// length为字符串数组string的总容量
void ReplaceSpace(char string[], int length) {
    if (string == NULL || length <= 0)
        return;
    
    // originalLength为字符串string的实际长度
    int orginalLength = 0;
    int numOfSpace = 0;
    int i = 0;
    while (string[i] != '\0') {  // 统计空格个数及字符串的原始长度
        ++originalLength;
        if (string[i] == ' ')
            ++ numOfSpace;
        ++i;
    }
    
    // newLength为把空格替换为'%20'之后的长度
    int newLength = originalLength + numOfSpace * 2;
    if (newLength > length) 
        return;
    
    // 定义两个指针,在字符串的后面进行复制和替换
    int indexOfOriginal = originalLength;
    int indexOfNew = newLength;
    while (indexOfOriginal >= 0 && indexOfNew > indexOfOriginal) {
        if (string[indexOfOriginal] == ' ') {  // 遇到空格
	    string[indexOfNew --] = '0';
	    string[indexOfNew --] = '2';
	    string[indexOfNew --] = '%';
        }else {
	    string[indexOfNew --] = string[indexOfOriginal];
        }
        -- indexOfOriginal;
    }
}
    注:这段代码来自《剑指offer》P47.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值