我必须编写一个具有以下规范的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;
}
所以这段代码显然是错误的......但它可以成功识别复制。 (我知道这是作业和我的耻辱....但我一直试图解决它几个小时。抱歉搞砸了代码。)
这里给出一个不是C字符串的char数组,因为它可以包含空字符。这意味着你应该忘记在处理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