манипуляции строк с ++ с помощью указателей, ноль в середине - PullRequest
0 голосов
/ 20 февраля 2019

Мне нужно написать функцию 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;
}

Так что этот код явно неверен ... но он может успешно идентифицировать дублирование.(Я знаю, что это домашняя работа и позор для меня .... но я пытался решить ее часами. Извините за испорченный код.)

1 Ответ

0 голосов
/ 20 февраля 2019

Вам дан массив символов, который не является строкой C, поскольку может содержать нулевые символы.Это означает, что вы должны забыть все, что вы могли знать о строках Си при обработке.

Он задается двумя указателями, один в начале, один за концом.Поскольку он должен быть обработан на месте, начальный указатель не изменится, поэтому ваша функция должна просто вернуть новый конечный указатель (то же самое определение: один после последнего сохраненного символа).

Как только это будет сказано,Ваш текущий код слишком сложен.Вам нужно только читать строку по одному символу за раз, сравнивать текущий символ с предыдущим и сохранять его, только если они отличаются.Простой способ - использовать 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...