题目:
请实现一个函数,将一个字符串中的每个空格替换成“@2019@”。
例如,当字符串为“We Are Javaer”,则经过替换之后的字符串为“We@2019@Are@2019@Javaer”。
要求:
时限限制1000ms, 空间限制32768k。
public class StringReplaceSpace {
public static void main(String[] args) {
StringBuffer str = getTestString(200000, 100);
// System.out.println("原始字符串 : [" + str.toString() + "]");
System.out.println();
long start1 = System.currentTimeMillis();
String reStr1 = replaceSpace1(str);
// System.out.println("处理结果 : [" + reStr1 + "]");
long end1 = System.currentTimeMillis();
System.out.println(">>>API执行时间 : " + (end1 - start1) + "ms");
System.out.println();
long start2 = System.currentTimeMillis();
String reStr2 = replaceSpace2(str);
// System.out.println("处理结果 : [" + reStr2 + "]");
long end2 = System.currentTimeMillis();
System.out.println(">>>String算法(从后往前)执行时间 : " + (end2 - start2) + "ms");
long start3 = System.currentTimeMillis();
String reStr3 = replaceSpace3(str);
// System.out.println("处理结果 : [" + reStr3 + "]");
long end3 = System.currentTimeMillis();
System.out.println(">>>String算法(从前往后)执行时间 : " + (end3 - start3) + "ms");
}
//A. API方式
private static String replaceSpace1(StringBuffer str) {
return str.toString().replaceAll(" ", "@2019@");
}
//B. String算法:从后往前
private static String replaceSpace2(StringBuffer str) {
if (str != null) {
//B1. 字符串拆分为字符数组
char[] chars = str.toString().toCharArray();
//B2. 从前往后统计空格数量
int count = 0;
for (int j = 0; j < chars.length; j++) {
if (chars[j] == ' ') {
count++;
}
}
//B3.从后往前替换空格为%20
char[] newchars = new char[chars.length + count * 5];//定义新的chars
int newlength = newchars.length - 1;
for (int i = chars.length; i > 0; ) {
char b = chars[i - 1];
if (b != ' ') {
newchars[newlength--] = b;
} else {
newchars[newlength--] = '@';
newchars[newlength--] = '9';
newchars[newlength--] = '1';
newchars[newlength--] = '0';
newchars[newlength--] = '2';
newchars[newlength--] = '@';
}
i--;
}
return String.valueOf(newchars);
}
return null;
}
//C. String算法:从前往后
private static String replaceSpace3(StringBuffer str) {
if (str != null) {
//B1. 字符串拆分为字符数组
char[] chars = str.toString().toCharArray();
//B2. 从前往后统计空格数量
int count = 0;
for (int j = 0; j < chars.length; j++) {
if (chars[j] == ' ') {
count++;
}
}
//B3.从前往后替换空格为%20
char[] newchars = new char[chars.length + count * 5];//定义新的chars
int newlength = 0;
for (int i = 0; i < chars.length; i++) {
char b = chars[i];
if (b != ' ') {
newchars[newlength++] = b;
} else {
newchars[newlength++] = '@';
newchars[newlength++] = '2';
newchars[newlength++] = '0';
newchars[newlength++] = '1';
newchars[newlength++] = '9';
newchars[newlength++] = '@';
}
}
return String.valueOf(newchars);
}
return null;
}
/**
* @Description 随机生成测试用例
*
* @param length 随机字符串总长度
* @param spacenum 随机插入的空格数量
* @return stringbuffer
*/
private static StringBuffer getTestString(int length, int spacenum) {
StringBuffer stringBuffer = new StringBuffer();
if (spacenum >= length) {
System.out.println("[警告]:空格数量不可以比字符串总长大。");
return null;
}
//1. 随机产生除空格外的字符串。
String string = "";
Random random = new Random();
for (int i = 0; i < length - spacenum; i++) {
string += (char) (random.nextInt(26) + 97);
}
//2.随机产生空格位置数组
int[] spaces = new int[spacenum];
for (int j = 0; j < spacenum; j++) {
int randomnum = random.nextInt(length);
if (j != 0) {
boolean flag = true;
for (int s = 0; s < j; s++) {
if (spaces[s] == randomnum) {
flag = false;
}
}
if (flag) {
spaces[j] = randomnum;
} else {
j--;
continue;
}
} else {
spaces[0] = randomnum;
}
}
spaces = orderIntArray(spaces);//冒泡排序 : 正序
//3.将字符串中插入空格
char[] newchars = new char[length];
char[] chars = string.toCharArray();
int n = 0;
for (int k = 0; k < newchars.length; k++) {
boolean flag = false;
for (int m = 0; m < spaces.length; m++) {
if (spaces[m] == k) {
flag = true;
break;
}
}
if (flag) {
newchars[k] = ' ';
} else {
newchars[k] = chars[n++];
}
}
return stringBuffer.append(newchars);
}
//数组冒泡:正序
private static int[] orderIntArray(int[] intArray) {
int temp;
for (int i = 0; i < intArray.length; i++) {
for (int j = i + 1; j < intArray.length; j++) {
if (intArray[i] > intArray[j]) {
temp = intArray[i];
intArray[i] = intArray[j];
intArray[j] = temp;
}
}
}
return intArray;
}
}
执行结果:
>>>API执行时间 : 8ms
>>>String算法(从后往前)执行时间 : 3ms
>>>String算法(从前往后)执行时间 : 3ms
算法分析:
第一种,java具有replaceAll()函数,直接实现但执行结果来看效率相对较低,当然这是在测试数据较大的情况下才会出现。
第二种,String算法,分为从后往前替换和从前往后,这主要是体现一种算法思维,从后往前替换可以减少字符移动次数,效率更高。