Удалить все слова с удвоенными буквами

401
27 декабря 2016, 00:39

Нужно использовать strtok, я не могу понять как мне проверить каждое слово из введённого массива символов, допустим:

char text[80];
cin.get(text, 80);
char *word = strtok(text, " ,.-?!");
while(text != 0)
{
    word = strtok(NULL, " ,.-?!");
}

Я понимаю, что мне в каждом слове нужно проверить предшествующий символ с последующим, но не могу понять как мне это правильно реализовать.

Answer 1

Вам не следует использовать функцию strtok, так как она изменяет исходную строку, и вам будет сложно из нее удалить слова с повторяющимися символами. Вам нужно самостоятельно сканировать исходную строку либо в цикле либо с использованием таких функций как strcspn и strspn и находить начало и конец слова в предложении.

Определить, содержит ли слово смежные повторяющиеся символы достаточно просто. Можно для этого написать простой цикл либо использовать стандартный алгоритм std::adjacent_find, объявленный в заголовке <algorithm>. Вот фрагмент кода, который демонстрирует, как это можно сделать первым или вторым способом

Предполагается, что слово в строке уже найдено, и начало слова содержится в переменной first, а первый символ после слова - в переменной last/

#include <algorithm>
//...
char s[] = "abc abbc";
size_t first = 0;
size_t last = 3;
while (++first != last && s[first] != s[first - 1]) ++first;
if (first == last) std::cout << "There is no adjacent equal characters" << std::endl;
else std::cout << "The word contains adjacent equal characters" << std::endl;
first = 0;
last = 3;
if (std::adjacent_find(s + first, s + last) == s + last)
{
    std::cout << "There is no adjacent equal characters" << std::endl;
}
else
{
    std::cout << "The word contains adjacent equal characters" << std::endl;
}
first = 4;
last = 8;
while (++first != last && s[first] != s[first - 1]) ++first;
if (first == last) std::cout << "There is no adjacent equal characters" << std::endl;
else std::cout << "The word contains adjacent equal characters" << std::endl;
first = 4;
last = 8;
if (std::adjacent_find(s + first, s + last) == s + last)
{
    std::cout << "There is no adjacent equal characters" << std::endl;
}
else
{
    std::cout << "The word contains adjacent equal characters" << std::endl;
}

Вывод этого фрагмента кода будет выгляджеть следующим образом

There is no adjacent equal characters
There is no adjacent equal characters
The word contains adjacent equal characters
The word contains adjacent equal characters

Как видно из вывода, оба подхода, использование вручную написанного цикла или использование стандартного алгоритма, дают один и тот же результат.

Теперь, зная начало и конец слова, вы можете уделить его из строки простым копированием подстроки, следующей за найденным словом в начальную позицию слова, тем самым "затирая" слово.

Answer 2

Лучше работать вот так:

for(char * s = strtok(text," ,.-?!"); s; s = strtok(nullptr," ,.-?!"))
{
    // Работаем с очередным словом s
}
READ ALSO
Таблица синуса и косинуса

Таблица синуса и косинуса

Ради оптимизации решил сделать табличку в которой будут лежать синусы и косинусыРисует почти как надо

316
Объектный полиморфизм

Объектный полиморфизм

Есть QTabWidget tabsВ нем лежат виджеты вкладок, в каждой вкладке есть layout, в этом layout'e QScrollArea со своим layout'om

339
Несколько классов в одном файле

Несколько классов в одном файле

Является ли дурным тоном описывать и реализовывать несколько классов в одном файле-заголовочнике и одномсрр-файле соответственно? Например,...

692
В созданном шаблоне отсутствует файл с исходным кодом

В созданном шаблоне отсутствует файл с исходным кодом

При создании шаблона проекта С++ в Visual Studio 2015 Update 3, проект собирается, шаблон создается, устанавливается, но в нем отсутствует файл с исходным...

351