我有一段C代码可以完全删除字符数组中的每一个字符,使原始数组的大小减半(如果大小为奇数,则为半+ 1)
..但我无法弄清楚它是如何运作的。
void del_str(char string[]) {
int i,j;
for(i=0, j=0; string[i]!=0; i++) {
if(i%2==0) {
string[j++]=string[i];
}
}
string[j]=0;
}
//
example input: 'abcdefgh'
output from that: 'aceg'
what I thought the output would be: 'aacceegg'
我不明白的是
string[j++]=string[i];
我可以编写省略每秒char的代码,因此输出将是:
'a c e g '
但是我无法解决这个问题。
或者,您如何编写一个完全删除原始数组中每个第n个字符及其空间的程序? (产生与上述代码相同的输出)
答案 0 :(得分:4)
此代码使用两个位置索引i
和j
。最初,两个索引都初始化为零。索引i
用于阅读; index j
用于写作。
索引i
在循环的每一步都会递增,因为增量i++
位于循环的标题中。另一方面,索引j
每隔一次迭代递增一次,因为j++
仅在i
为偶数时才会发生。索引i
始终与索引j
一样接近或接近字符串的结尾,因为它移动得更快"。
Null终结符位于循环结尾的j
的最终位置,表示字符串结束的新位置。
也许通过一个小例子可以更容易看到。考虑"abcdef"
的初始字符串。它在算法开始时在内存中的表示如下:
'a' 'b' 'c' 'd' 'e' 'f' '\0'
以下是循环的每个步骤后它将如何变化:
'a' 'b' 'c' 'd' 'e' 'f' '\0'
'a' 'c' 'c' 'd' 'e' 'f' '\0'
'a' 'c' 'e' 'd' 'e' 'f' '\0'
'a' 'c' 'e' '\0' 'e' 'f' '\0'
由于C字符串会忽略'\0'
之后的所有内容,因此" tail" 'e' 'f' '\0'
的{{1}}不被视为字符串的一部分。
答案 1 :(得分:1)
i和j不是最清晰的变量名。也许将j
重命名为output
会有所帮助。
注意更新j
时,仅当您处于奇数位置时。所以i
正在遍历整个列表,而j
会将读取内容从i
复制回j
位置,覆盖之前的内容。最后一行string[j]=0
终止了您的字符串。
答案 2 :(得分:1)
你忘记了if(i%2==0)
这是至关重要的。这条线基本上会跳过每一个字符。然后,您识别的行可以分为两部分:
string[j]=string[i]; // Overwrite the character at position j
j++; // Now increase j
变量i
会在阅读时跟踪您已达到的字符串的位置; j
用于写作。最后,在位置j
写0以终止字符串。