用不同的和更多的字符替换特定的字符

Replacing specific chars with different and more chars

我正在尝试根据以下问题从一本书中做一个有趣的练习:

For our dynamically allocated strings, create a function replaceString that takes three parameters, each of type arrayString: source, target, and replaceText. The function replaces every occurrence of target in source with replaceText. For example, if source points to an array containing abcdabee, target points to ab, and replaceText points to xyz, then when the function ends, source should point to an array containing xyzcdxyzee.

我将每次出现的目标(在本例中为 ab)替换为 replaceText,在本例中为 char * 中的 xyz。

对于本练习,本书使用 0 来标记 char * 终止,并使用 typedef 来标记 char *。我编写了以下函数来测试 replaceString。

arrayString 为 typedef char *arrayString

void replaceStringTester() {
    arrayString test = new char[8];
    test[0] = 'a';
    test[1] = 'b';
    test[2] = 'c';
    test[3] = 'd';
    test[4] = 'a';
    test[5] = 'b';
    test[6] = 'e';
    test[7] = 'e';
    test[8] = 0;
    arrayString target = new char[3];
    target[0] = 'a';
    target[1] = 'b';
    target[3] = 0;
    arrayString replaceText = new char[4];
    replaceText[0] = 'x';
    replaceText[1] = 'y';
    replaceText[2] = 'z';
    replaceText[3] = 0;
    replaceString(test, target, replaceText);
    cout << test;
}

以及以下函数来查找 arrayString 的长度

int length(arrayString as) {
    int count = 0;
    while (as[count] != 0) {
        ++count;
    }
    return count;
}

到目前为止我的想法是,遍历源arrayString,检查源是否从目标的第一个字符开始?如果是,遍历 target 并检查其余是否对齐。我已经为它编写了以下功能,但是我不确定它是否完全符合我起草的功能。

void replaceString(arrayString &source, arrayString target, arrayString replaceText) {

    int sourceLength = length(source);
    int targetLength = length(target);
    int replaceTextLength = length(replaceText);
    int targetPresent = 0;

    for (int i = 0; i < sourceLength; ++i) {
        if (source[i] == target[0]) {
            int count = 0;
            for (int k = 0; k < targetLength; ++k) {
                if (target[k] == source[i + k]) {
                    ++count;
                }
            }
            if (count == targetLength) {
                ++targetPresent;
            }
        }
    }

    int newStringLength = sourceLength + (replaceTextLength - targetLength) * targetPresent + 1;
    arrayString newString = new char[newStringLength];
    newString[newStringLength] = 0;

    int j = 0;
    int i = 0;

    while (j < newStringLength) {
        if (source[j] == target[0]) {
            bool targetAcquired = false;
            for (int k = 0; k < targetLength; ++k) {
                if (target[k] == source[j + k]) {
                    targetAcquired = true;
                } else {
                    targetAcquired = false;
                    break;
                }
            }
            if (targetAcquired) {
                for(int k = 0; k < replaceTextLength; ++k) {
                    newString[i] = replaceText[k];
                    ++i;
                }
                j += targetLength;
            }
            if (!targetAcquired) {
                newString[i] = source[j];
                ++j;
                ++i;
            }
        } else {
            newString[i] = source[j];
            ++j;
            ++i;
        }
    }

    delete[] source;
    source = newString;
}

编辑:

我已经解决了这个问题,方法是在每个相应的 stringArray 中为我们的位置实现两个跟踪器,然后使用布尔值过滤 what is in where。感谢您的帮助。

计算您分配了多少个元素:

test[0] = 'a'; // 1
test[1] = 'b'; // 2
test[2] = 'c'; // 3
test[3] = 'd'; // 4
test[4] = 'a'; // 5
test[5] = 'b'; // 6
test[6] = 'e'; // 7
test[7] = 'e'; // 8
test[8] = 0;   // 9

您已经分配了 9 个元素。数组中是否有9个元素?

arrayString test = new char[8];

没有。数组中没有 9 个元素。有8个,你越界访问,程序行为未定义


arrayString being typedef char *arrayString

不要像这样使用混淆。它降低了可读性并且没有任何优势。

对于使用此 typedef 的初学者

typedef char *arrayString;

是个坏主意。例如,如果你需要声明一个指向常量字符串的指针,那么这个声明

const arrayString p;

不会表示

const char *p;

意思是

char * const p;

这和上面的声明不一样..

你的函数的第二个和第三个参数应该声明为const char *类型,因为它们在函数内没有改变,

函数应按以下方式声明

char * replaceString( char * &source, const char *target, const char *replaceText );

在函数中,您首先需要计算字符串 target 在字符串 source 中出现的次数。当使用此信息和字符串长度 replaceText 时,如果需要,您需要动态分配一个新的字符数组。当只是将源字符串复制到动态分配的数组中时,用目标字符串替换替换字符串。

之后您应该删除源字符串并将其指针分配给新形成的字符串。

注意在header<cstring>中声明了标准的C字符串函数strstr可以简化你的代码。还可以使用另一个标准 C 字符串函数 strlen 来查找字符串的长度。否则你应该自己写。