Удалить лишние пробелы из строки (на месте) - PullRequest
3 голосов
/ 17 февраля 2010

Хорошо, поэтому я писал ранее о попытке (без каких-либо встроенных функций) удалить дополнительные пробелы, поэтому

"this is <insert many spaces!> a test" вернется

"this is a test"

Удалить пробелы из строки, но не в начале или в конце

Поскольку это было домашнее задание, я не просил полного решения, и некоторые добрые люди предоставили мне следующее

"Если вам нужно сделать это на месте, то создайте два указателя. Один указывает на читаемый символ, а другой на копируемый символ. Когда вы встретите лишний пробел, адаптируйте указатель« запись », чтобы он указывал на следующий непробельный символ. Скопируйте в положение чтения символ, на который указывает символ записи. Затем переместите указатели чтения и записи на символ после копирования символа. "

Проблема в том, что теперь я хочу полностью разбить мой компьютер на куски, так как он оооочень раздражен им. В то время я не понимал, что не могу использовать массив char, поэтому использовал для этого индексы массива, я думал, что смогу найти способ заставить его работать, но сейчас я просто использую указатели, и мне это очень сложно. Мне действительно нужна помощь, а не полные решения. Пока это то, что я делаю;

1) создайте указатель с именем write, поэтому я не буду писать в

2) создайте указатель с именем read, поэтому я не знаю, откуда читать

(оба эти указателя теперь будут указывать на первый элемент массива char)

while (read != '\0')
    if read == a space 
        add one to read
        if read equals a space now 
            add one to write
            while read != a space {
                 set write to = read
            }
                 add one to both read and write
    else 
        add one to read and write 
        write = read  

Ответы [ 7 ]

6 голосов
/ 17 февраля 2010

Попробуйте просто сделать это символ за символом на листе бумаги и сначала выясните, что вы делаете, а затем переведите это в код.

Если у вас все еще возникают проблемы, попробуйте сначала сделать что-то попроще, например, просто скопировать строковый символ для символа, не беспокоясь о его части «удалить дубликаты» - просто чтобы убедиться, что вы не сделали глупости ошибка в другом месте.

2 голосов
/ 17 февраля 2010

Совет попытаться сделать это сначала ручкой и бумагой - это хорошо. И это действительно не имеет значения, если вы делаете это с помощью указателей или индексации массива; Вы можете использовать либо указатель чтения и записи, либо индекс чтения и записи.

Подумайте, когда вы хотите продвинуть индексы вперед. Вы всегда перемещаете индекс записи вперед после написания символа. Вы перемещаете индекс чтения вперед, когда читаете символ.

Возможно, вы могли бы начать с некоторого кода, который просто перемещается по строке, но фактически не меняет его. А затем вы добавляете логику, которая пропускает дополнительные пробелы.

1 голос
/ 18 февраля 2010

Вот решение, которое имеет только один цикл (без внутреннего цикла для пропуска пробелов) и без данных о состоянии:

dm9pZCBTdHJpcFNwYWNlcyAoY2hhciAqdGV4dCkNCnsNCiAgY2hhciAqc3JjID0gdGV4dCwgKmRl
c3QgPSB0ZXh0Ow0KICB3aGlsZSAoKnNyYykNCiAgew0KICAgICpkZXN0ID0gKihzcmMrKyk7DQog
ICAgaWYgKCpzcmMgIT0gJyAnIHx8ICpkZXN0ICE9ICcgJykNCiAgICB7DQogICAgICArK2Rlc3Q7
DQogICAgfQ0KICB9DQogICpkZXN0ID0gMDsNCn0NCg==

Выше кодируется Base64, так как это домашнее задание. Для декодирования скопируйте вышеуказанный блок и вставьте в этот веб-сайт , чтобы декодировать его (вам необходимо установить переключатель «Декодировать»).

1 голос
/ 17 февраля 2010
char p[] = "this is              a test";
char *readptr = &p[0];
char *writeptr = &p[0];

int inspaces = 0;
while(*readptr) {
 if(isspace(*readptr)) {
   inspaces ++;
 } else {
  inspaces = 0;
 }
 if(inspaces <= 1) {
  *writeptr = *readptr;
   writeptr++;
 }
 readptr++;
}
*writeptr = 0;
0 голосов
/ 18 февраля 2010

Можете ли вы использовать регулярные выражения? Если так, это может быть действительно легко. Используйте регулярное выражение для замены \s{2,}? на один пробел. \s означает любой пробел (табуляция, пробел, загрузка каретки ...); {2,} означает 2 или более; ? означает не жадный. (Отказ от ответственности: мое регулярное выражение может быть не лучшим, которое вы могли бы написать, так как я не являюсь профессионалом регулярных выражений. Кроме того, это синтаксис .net, поэтому библиотека регулярных выражений для C может иметь немного другой синтаксис.)

0 голосов
/ 17 февраля 2010

при условии, что вы пытаетесь написать функцию вроде:

void removeSpaces(char * str){

   /* ... stuff that changes the contents of str[] */

}

Вы хотите просканировать строку на наличие последовательных пробелов, чтобы указатель записи всегда отставал от указателя чтения. Переместите указатель чтения в место, где вы указываете на пробел, но следующий символ не пробел. Если ваши указатели чтения и записи не совпадают, то указатель записи должен указывать на начало последовательности пробелов. Разница между указателем записи и чтения (т.е. read_pointer - write_pointer) скажет вам количество последовательных пробелов, которые необходимо перезаписать, чтобы закрыть пробел. Когда разница больше нуля, (префикс) продвигает оба указателя на столько позиций, копируя символы по мере продвижения. Когда вы прочитали указатель в конце строки ('\ 0'), вам нужно закончить.

0 голосов
/ 17 февраля 2010

Почему бы вам не сделать что-то подобное:

создайте второй символ ** той же длины, что и первый. Когда вы пробегаете первый массив со своими указателями, оставляйте дополнительный указатель на последнем месте, которое вы видели. Если последний пробел, который вы видели, был предыдущим элементом, то вы не копируете этот символ во второй массив.

Но я бы начал с того, что каждый символ проходит через символ ** и печатает каждый символ. Если вы можете сделать это, вы можете скопировать их во второй символ **.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...