0

我必须编写一个具有以下规范的 c++ 函数:

独特

删除两个参数指针之间的重复章程。字符串保留在其原始位置。

param first - 指向字符串开头的指针

参数 last - 指向最后一个宪章之后的数据的指针

return - 指向新数据系列第一个字符的指针

如果输入是“H\0elllo C++++ +!#”,则输出是“H\0elo C++!#”。我无法弄清楚如何忽略中间的终止空值。这是我迄今为止最好的方法:

char *sajat::unique(char *first, char *last){
char* moving = first + 1;
char* follower = first;

while (moving != last)
{
char *sentinel = first; 
    if (*follower == *moving)
    {
    counter++;
    sentinel = follower; //here was the duplication
        while (follower != last)
        {
            *follower = *moving;
            follower++;
            moving++;
        }
        sentinel = follwer;
        moving = follower + 1;
    }
    moving++;         
    follower++;
   }
return first - counter;
}

所以这段代码显然是错误的......但它可以成功识别重复。(我知道这是家庭作业,让我感到羞耻……但我已经尝试解决了好几个小时。抱歉,代码混乱了。)

4

1 回答 1

1

此处为您提供了一个不是 C 字符串的 char 数组,因为它可以包含空字符。这意味着在处理 C 字符串时,您应该忘记所有可能知道的有关 C 字符串的信息。

它由 2 个指针给出,一个在开始处,一个在结束处。由于要就地处理,开始指针不会改变,所以你的函数应该只返回新的结束指针(仍然是相同的定义:超过最后一个保留的字符)。

一旦这样说,您当前的代码就太复杂了。您只需一次读取一个字符,将当前字符与前一个字符进行比较,并仅在它们不同时才保留它。一种简单的方法是使用 2 个指针,一个用于读取,一个用于写入,在每次迭代时递增读取指针,并且仅在必须保留字符时才递增写入指针。至于前面的值,一个惯用的方式是把它初始化为一个不能用字符表示的int值。

该函数简化为:

char *sajat::unique(char *first, char *last){
    char *rd = first, *wr = first;
    int prev = UCHAR_MAX + 1;       // cannot be a character value

    while (rd != last) {
        if (prev != *rd) {
            prev = *wr++ = *rd;
        }
        rd++;
    }

return wr;
}

演示代码:

#include <iostream>
#include <string>
#include <climits>

char *unique(char *first, char *last){
    char *rd = first, *wr = first;
    int prev = UCHAR_MAX + 1;       // cannot be a character value

    while (rd != last) {
        if (prev != *rd) {
            prev = *wr++ = *rd;
        }
        rd++;
    }

return wr;
}

int main() {
    char tst[] = "H\0elllo C+++++ +!#";
    char *last = unique(tst, tst+sizeof(tst) - 1);  // reject the terminating null

    std::cout << std::string(tst, last) << std::endl;  // first display the result as a string

    for (char *ix=tst;ix<last; ix++) {              // then every character in hexa
        std::cout << std::hex << " " << (unsigned int)(unsigned char) *ix;
    }
    std::cout << std::endl;
    return 0;
}

在我的 ASCII 系统上,它显示:

Helo C+ +!#
 48 0 65 6c 6f 20 43 2b 20 2b 21 23
于 2019-02-20T09:27:09.273 回答