c++ 使用指针进行字符串操作,中间为空

Posted

技术标签:

【中文标题】c++ 使用指针进行字符串操作,中间为空【英文标题】:c++ string manipulation with pointers, null in middle 【发布时间】:2019-02-20 08:20:27 【问题描述】:

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

独一无二

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

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

param 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;

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

【问题讨论】:

你可以使用 std::remove_if 吗? 我不明白这个问题。什么是重复?您上面的输出字符串有两个'+' 和两个' ',它们不是重复的吗?为什么要忽略 '\0' 字符?您的问题描述中没有任何内容表明您必须忽略它。无论如何,在这种情况下忽略它意味着什么?您应该返回的“新数据系列”是什么? 这里有重复:相同的两个字符一个接一个。我想保留 \0 字符,你是对的。忽略我的意思是不使用第一个作为终止字符。新数据系列是没有重复的字符串。对不起,我不清楚。 @Tom 我会尝试 remove_if,谢谢。 【参考方案1】:

这里给你一个 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

【讨论】:

非常感谢您的解决方案和详细解释!

以上是关于c++ 使用指针进行字符串操作,中间为空的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode0680.验证回文字符串 Ⅱ

使用字符串流?

Go 字符串操作

实验12——指针的基础应用2

实验12——指针的基础应用2

c++中的c_str()