候选单通解决方案。
对于str
每个字符,递归。递归之后,进行更换。
它确实递归严重。
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
// return 0:success else 1:fail
static int inplace_help(char *dest, const char *src, int pattern,
const char* replacement, size_t rlen, size_t mlen) {
printf("'%p' '%s' %c\n", dest, src, pattern);
if (*src == pattern) {
if (rlen > mlen) return 1;
if (inplace_help(dest + rlen, src + 1, pattern, replacement, rlen,
mlen - rlen)) return 1;
memcpy(dest, replacement, rlen);
return 0;
}
if (mlen == 0) return 1;
int replace1 = *src;
if (*src) {
if (inplace_help(dest + 1, src + 1, pattern, replacement, rlen, mlen - 1)) {
return 1;
}
}
*dest = replace1;
return 0;
}
void inplace(char *str, const char pattern, const char* replacement,
size_t mlen) {
if (pattern == 0) return;
if (mlen == 0) return;
if (*replacement == 0) return; // Insure str does not shrink.
inplace_help(str, str, pattern, replacement, strlen(replacement), mlen - 1);
}
int main(void) {
char str[1000] = "eeeeec";
inplace(str, 'e', "1234", sizeof str);
printf("'%s'\n", str); // --> '12341234123412341234c'
return 0;
}
“如果原始字符串长度为n,并且只包含Ë ,我们需要2(n-1)+ 2(n-2)+ ... + 2个移位“。不,这是不正确的。每个字母只移动一次。例如:“abcdef”。右移一个字母的意思是,复制'f'一个字符下来,复制'e'一个字符下来,等等。你正在从字符串的末尾开始工作。这并不意味着从字符串的前面连续扫描,正如您所暗示的那样。 – kaylum
如果原始字符串是eeeec,则新字符串应该是123123123123c。如果我们知道新字符串的长度,我们可以将c直接移动到最终位置,然后逐个添加123。不知道长度,当第一个e匹配时,我们将所有剩下的eeec 2个字节向右移动,这需要4个移动。当我们遇到第二个e时,我们需要另外3个动作.. –
好吧,你是对的。但那是因为你的问题还没有明确说明(即使你已经开始了一个新问题)。那么,至少我不清楚你想要取代所有的出现(是的,我可能应该假设 - 但这就是为什么需求应该总是清楚明确地指定,而不是为假设留出空间)。 – kaylum