剑指offer第二版——面试题5(java)

面试题5:替换空格

请实现一个函数,把字符串中的每个空格替换成“%20”。例如输入“We are happy”,则输出”We%20are%20happy”.

原因:在网络编程中,如果URL参数中含有特殊字符,如:空格、“#”等,可能导致服务器端无法获得正确的参数值。我们需要将这些特殊符号转换成服务器识别的字符。转换规则是在“%”后面跟上ASCII码的两位十六进制的表示。比如:空格的ASCII码是32,即十六进制的0x20,因此空格被替换成“%20”
①StringBuilder的方法

②书上的从后往前挪的方法

// 用StringBuilder
class Q5 {
	public static void main(String[] args) {
		String s = "we are happy";
		String s1 = " we are happy";
		String resultString = getResult(s1);
		System.out.println(resultString);
	}  
	
	public static String getResult(String s) {
		StringBuilder strb = new StringBuilder();
		for(int i=0;i<s.length();i++) {
			if(s.charAt(i)==' ') {
				strb.append("%20");
			}else {
				strb.append(s.charAt(i));
			}
		}
		return strb.toString();
	}
}

先遍历一次字符串,统计出字符串中空格的总数,计算出替换之后字符串的总长度。

每替换一个空格,长度增加2,因此替换以后的字符串的长度等于原来的长度加上2乘以空格的数目
 

class Q5 {
	public static void main(String[] args) {
		String s = "we are happy";
		String s1 = "  ";
		char[] resultString = getResult(s1);
		for(int i=0;i<resultString.length;i++) {
			System.out.printf("%c",resultString[i]);
		}
	}  
	
	public static char[] getResult(String s) {
		int count = 0;
		for(int i=0;i<s.length();i++) {
			if(s.charAt(i)==' ') {
				count++;
			}
		}
        //新长度为2*count+s.length()  边界索引值为2*count+s.length()-1
		char[] chs = new char[2*count+s.length()];
		int loc = s.length()-1;
		for(int i = 2*count+s.length()-1;i>=0;i--) {
			System.out.printf("loc:%d,i:%d,char:%c\n", loc,i,s.charAt(loc));
			if(s.charAt(loc)!=' ') {
				chs[i] = s.charAt(loc);
				loc--;
			}else {
				chs[i--] = '0';
				chs[i--] = '2';
				chs[i] = '%';
				loc--;
			}
		}
		return chs;
	}
}

相关题目:

两个排序的数组A1和A2,内存在A1的末尾有足够多的空余空间容纳A2,。

实现一个函数——把A2中的所有数字插入A1中,并且所有的数字是排序的

方法:从尾到头比较A1和A2中的数字,并把较大的数字复制到A1中的合适位置

// 从后往前插入
class Q5_Additional {
	public static void main(String[] args) {
		int[] l1 = new int[] {1,2,4,5,7,9};
		int[] l2 = new int[] {2,3,6,7,9,10};
		int[] ln = getMerge(l1,l2);
		for(int i=0;i<ln.length;i++) {
			System.out.printf("%d ", ln[i]);
		}
	}  
	
	public static int[] getMerge(int[] l1,int[] l2) {
		int[] ln = new int[l1.length+l2.length];
		int loc1 = l1.length-1;
		int loc2 = l2.length-1;

		for(int i=ln.length-1;i>=0;i--) {
			// 先判断条件,条件满足再判断大小,如果不满足不越界会报错
			if(loc2>=0&&loc1>=0) {
				if(l1[loc1]>=l2[loc2]) {
					ln[i] = l1[loc1];
					loc1--;
				}else{
					ln[i] = l2[loc2];
					loc2--;
				}
			}else {
				if(loc1<0) {
					ln[i] = l2[loc2--];
				}else {
					ln[i] = l1[loc1--];
				}
			}
		}
		return ln;
	}
}

举一反三:

在合并两个数组(包括字符串)时,如果从前往后复制每个数字(或字符)则需要重复移动数字(或字符)多次,则可以考虑从后往前复制,这样能减少移动的次数,从而提高效率。

猜你喜欢

转载自blog.csdn.net/qq_22527013/article/details/88317965