我正在解决用public static void replaceSpaces(String input, int length) {
char[] str = input.toCharArray();
int spaceCount = 0;
for(int i = length - 1; i >= 0; i--){
if(str[i] == ' ') {
spaceCount++;
}
}
int newLength = length + spaceCount * 2;
str[newLength] = '\0';
for(int i = length - 1; i >= 0; i--) {
if(str[i] == ' ') {
str[newLength - 1] = '0';
str[newLength - 2] = '2';
str[newLength - 3] = '%';
newLength = newLength - 3;
System.out.println(str);
} else {
str[newLength - 1] = str[i];
newLength = newLength - 1;
System.out.println(str);
}
}
}
替换空格来破解编码专访第5版的问题:
编写一个方法,用'%20'替换字符串中的所有空格。您可以假设字符串在字符串末尾有足够的空间来容纳其他字符,并且您将获得" true"字符串的长度。 (注意:如果在Java中实现,请使用字符数组,以便您可以就地执行此操作)
我的算法是:
Mr John Smith h
Mr John Smith th
Mr John Smith ith
Mr John Smithmith
Mr John SmitSmith
Mr John S%20Smith
Mr John n%20Smith
Mr Johnhn%20Smith
Mr Johohn%20Smith
Mr JoJohn%20Smith
Mr%20John%20Smith
Mr%20John%20Smith
Mr%20John%20Smith
打印出该功能的每一步,这是我的输出:
17
我有两个问题:
我们知道字符串的新长度为[newLength - 1]
。我不明白的是,为什么我们需要[newLength]
代替str[newLength] = '\0';
。我们有兴趣更换目前的指数,不是吗?或者是因为新长度是17,但是当转换为索引时,它实际上是16(第0个索引)。
目的是什么:{{1}}
答案 0 :(得分:1)
我们并非都有这本书,但是从待处理的编辑中,我看到确切的问题是:
编写一个方法,用'%20'替换字符串中的所有空格。您可以假设字符串在字符串末尾有足够的空间来容纳附加字符,并且您将获得字符串的“true”长度。 (注意:如果在Java中实现,请使用字符数组,以便您可以就地执行此操作)
从破解编码面试第5版
因此,它表示您的input
参数应为char[]
。
由于您正在更改文本的长度,因此您的方法需要返回新的长度。
问题1:
我们知道字符串的新长度是17.我不明白的是,为什么我们需要[newLength - 1]而不是[newLength]。我们有兴趣更换目前的指数,不是吗?或者是因为新长度是17,但是当转换为索引时,它实际上是16(第0个索引)。
你自己回答了。如果长度为17,则索引为0到16.如果数组长度仅为17,则使用IndexOutOfBoundsException
访问索引17。
问题2:
目的是什么:str [newLength] ='\ 0';
无论如何。它是无效的,在Java中没有用处。删除它。
Java字符串有一个length()
。在C中,字符串是零终止的,但不是Java。
要测试代码,请尝试使用以下代码运行:
char[] buffer = { 'M','r',' ','J','o','h','n',' ','S','m','i','t','h','*','*','*','*' };
int inLen = 13;
System.out.println("buffer: '" + new String(buffer) + "'");
System.out.println("inLen : " + inLen);
System.out.println("input : '" + new String(buffer, 0, inLen) + "'");
int outLen = replaceSpaces(buffer, inLen);
System.out.println("outLen: " + outLen);
System.out.println("result: '" + new String(buffer, 0, outLen) + "'");
输出应为:
buffer: 'Mr John Smith****'
inLen : 13
input : 'Mr John Smith'
outLen: 17
result: 'Mr%20John%20Smith'
在方法中访问input[17]
会抛出IndexOutOfBoundsException
。
以下是一个基于所显示代码的可能实现,它遵循引用文本,并在替换所有空格后停止处理。
public static int replaceSpaces(char[] str, int length) {
int spaceCount = 0;
for (int i = length - 1; i >= 0; i--)
if (str[i] == ' ')
spaceCount++;
int shift = spaceCount * 2;
int newLength = length + shift;
for (int i = newLength - 1; shift > 0; i--) {
char c = str[i - shift];
if (c != ' ') {
str[i] = c;
} else {
str[i] = '0';
str[--i] = '2';
str[--i] = '%';
shift -= 2;
}
}
return newLength;
}
这将产生上述测试代码的预期输出。
答案 1 :(得分:1)
下面发布的代码效果很好。干杯。 Sample Output
test = 'pam' -> map
test = 'enni' -> nine
test = 'yfunn' -> funny
答案 2 :(得分:0)
我相信您的直接问题已在评论中得到解答,因此我将重点关注所写方法的问题。
忽略基本String
类(以及许多其他第三方字符串实用程序类)中已存在此功能的事实,我们仍然可以编写基本的字符串替换函数。问题中写的函数似乎不是为Java编写的,并且不返回任何值,因为字符串是不可变的意味着函数不可能实现其名称。
相反,我们需要创建一个新数组,我们将现有字符复制到,同时替换我们遇到的任何空格%20。然后,我们将此数组作为新的String
返回。方便的是,Java有一个类,它封装了一个可变大小的字符数组,我们可以用它来组装名为StringBuilder
的新String。
因此,Java中更简单且有效(但未优化)的替换函数可能如下所示:
public static String replaceSpaces(String input)
{
if (input == null) return null;
// New string builder with some padding to account for replacements...
// Padding was chosen pretty arbitrarily, there are certainly better values.
StringBuilder builder = new StringBuilder(input.length() + 128);
for (int i = 0; i < input.length(); i++)
{
char c = input.chatAt(i);
if (c == ' ') {
builder.append("%20");
} else {
builder.append(c);
}
}
return builder.toString();
}
在开头将整个String转换为char[]
可能更为理想,并迭代数组而不是使用String.charAt(i)
。我们可以根据预期的空间数将现有字符串的长度乘以某个常量,为StringBuilder
选择更合适的填充。对于非常大的字符串,在声明我们的数组之前首先计算空格的数量甚至是有意义的,但这些优化留给了读者。
答案 3 :(得分:0)
@Test public void replaceTest() {
String s = "Mr John Smith ";
char[] chars = s.toCharArray();
int length = 13;
char[] chars1 = subString(chars, length);
//actualString = actualString.replace(" ", "%20");
Assert.assertEquals(replace(chars1, "%20"), "Mr%20John%20Smith");
}
private char[] subString(char[] chars, int length) {
char[] newChar = new char[length];
for (int i = 0; i < length; i++) {
newChar[i] = chars[i];
}
return newChar;
}
private String replace(char[] chars, String s) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
if (chars[i] == ' ') {
builder.append(s);
} else {
builder.append(chars[i]);
}
}
return builder.toString();
}