Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
zlodeyxgm
3 / 3 / 4
Регистрация: 08.09.2015
Сообщений: 63
#1

Удалить из текста все слова заканчивающиеся на гласную букву - C++

21.04.2016, 12:24. Просмотров 1248. Ответов 4
Метки нет (Все метки)

Использовать можно только массив символов, переменные string и их функции запрещены(

Начал пытаться продумывать решение сам и пришел к чему то такому: (просто наброски)

C++
1
2
3
4
5
6
7
const gl[]="йуеаоэяию";
char t[] = "какой то текст с гласными на конце"
int s=strlen(t);
for (int i=0; i<s; i++) 
//Вот тут была такая идея сверять каждый символ и последующий за ним на то, входят ли они в массив нужных нам символов. (1 массив: гласные. 2 массив - знаки конца слова, запятые. пробел и прочее)
написал логическую функцию для проверки, входит ли данный символ в массив gl символов. 
Теперь думаю, как удалять слово в конце которого нужная нам буква. Скорее всего прийдется создать доп массив символов...
Подскажите пожалуйста, кто что сможет)
http://www.cyberforum.ru/cpp-beginners/thread1689196.html
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.04.2016, 12:24
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Удалить из текста все слова заканчивающиеся на гласную букву (C++):

Ввести строку , вывести только слова, заканчивающиеся на гласную букву.
Ввести строку , вывести только слова, заканчивающиеся на гласную букву. ...

Вывести из файла все слова, которые начинаются на гласную букву
Вивести из файла все слова котрые начинаются на гласную букву. Слова записаны...

В заданном массиве найти все слова, начинающиеся и заканчивающиеся на одну и ту же букву
Дан массив символов, в нём нужно найти все слова которые начинаются и...

Распечатать все слова из каждой строки, начинающиеся и заканчивающиеся на заданную букву.
Строки состоят из слов, разделенных пробелами. Распечатать все слова из каждой...

Найти и вывести все слова начинающиеся и заканчивающиеся на одну и ту же букву (комментирование кода)
Прокомментируйте пожалуйста код: /* Ввести строку длинной до 500...

4
meJevin
156 / 148 / 92
Регистрация: 18.11.2015
Сообщений: 674
Завершенные тесты: 1
21.04.2016, 14:47 #2
Блин, только так.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <cstring>
 
int main() {
    setlocale(LC_ALL, "");
 
    char* gl = "йуеаоэяию";
    char* text = "Как то текст с гласными на конце кок";
 
    char* newText = new char[strlen(text)];
 
    int lastStop = 0, lastIter = 0;
    for (int i = 0; text[i] != '\0'; i++) {
        bool copyIt = false;
 
        if (text[i] == ' ') lastStop = i;
 
 
        if (text[i + 1] == ' ' || text[i + 1] == '\0') {        // тут еще можно добавить || text[i+1] == '\n' или что-то подобное, если текст содержить несколько строк
 
            for (int j = 0; gl[j] != '\0'; j++) {
                if (text[i] == gl[j]) {
                    copyIt = false; break;
                }
                copyIt = true;
            }
 
        }
 
        if (copyIt == true) {
            for (int j = lastStop; j <= i; j++, lastIter++)
                newText[lastIter] = text[j];
        }
    }
 
    for (int i = 0; i < lastIter; i++)
        std::cout << newText[i];
 
    std::cout << "\n";
 
    return 0;
}
Добавлено через 6 минут
Фиговато вышло, потому что если в тексте будут какие-то знаки, кроме букв, то кранты.

Добавлено через 6 минут
Я думаю ньюанс со знаками можно пофиксить так. В строке 19 у меня программа смотрит, а не пробел ли спереди знака, который я сейчас смотрю? Потом, если там и вправду пробел, то программа смотрит, на каком символе она остановилась. Можно сделать еще один цикл, который будет обратно идти по тексту, пока не встретит букву (isalpha() в помощь), а потом уже ту букву сравнивать с массивом гласных. Как-то так.

Добавлено через 17 минут
Или что-то на подобии этого еще можно while (ispunct(text[i])) i--;
1
zlodeyxgm
3 / 3 / 4
Регистрация: 08.09.2015
Сообщений: 63
22.04.2016, 18:09  [ТС] #3
Спасибо. ТУт мыль пришла а если с помощью strtok разбить все на слова и каждое из них проверять. Если оно не подходит под условие, то добавляем его к новому массиву чаров. Попробовал осуществить, но наткнулся на ошибки.
Как создать массив чаров и сделать его пустым? У меня вечно он заполнен символами или ММММММм или ННННННННН
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
const char gl[] = "аоэиуыеёюя";
bool func(char t)
{
    bool z=false;
    for (int j=0; (j<10) && (!z); j++)
        if (gl[j] == t) z = true;
    return z;
};
 
int main()
{
    setlocale(LC_ALL,"Rus");
    char text[] = "Какой-то текст с гласными буквами, тут!";
    int size = strlen(text);
    char *word = new char[size];
    char *newtext = new char[size];
    word = strtok (text," ");
    if (!func(word[strlen(word)])) strcat(newtext, word);
    while (word != NULL)                         // пока есть лексемы
    {
        cout << word  << "\n";
        word = strtok (NULL, " ");
        if (!func(word[strlen(word)])) strcat(newtext, word);
    }
    cout<<endl;
        cout<<newtext<<endl;
delete [] word;
delete [] newtext;
        return 0;
}
Добавлено через 9 часов 56 минут
Все еще работаю в этом плане, но кардинально изменил метод:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
using namespace std;
const char gl[] = "аоэиуыеёюя";
bool func(char t)
{
    bool z=false;
    for (int j=0; (j<10) && (!z); j++)
    {
        if (gl[j] == t) z = true;
    }
    return z;
};
 
void strnew(int a, int b, char t[])
{
    int size = strlen(t);
    for (int j=a; j<size; j++)
    {
        t[j] = t[b];
        b++;
    }
};
 
int main()
{
    setlocale(LC_ALL,"Rus");
    char text[] = "Рт Текст из пяти слов и ого себе .";
    int size = strlen(text);
 
    int end=0, start=0;
    for (int i=0; i<size; i++)
    {
        if (text[i] == ' ') 
        {
            if (func(text[i-1]))
            {
                end = i;
                strnew(start,end,text);
            }
            start = i+1;
        }
    }
    size = strlen(text);
    for (int i=0; i<size; i++)
        cout<<text[i];
    cout<<endl;
    system("pause");
    return 0;
}
По началу все идет как по маслу, но после первого удаления начинаются сдвиги и проблемы. Можете подсказать , как адаптировать код)
0
meJevin
156 / 148 / 92
Регистрация: 18.11.2015
Сообщений: 674
Завершенные тесты: 1
24.04.2016, 19:59 #4
zlodeyxgm, я думаю, самое стабильное решение будет со string и vector, у меня вот так вышло:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <vector>
#include <string>
 
const char gl[] = "аоэиуыеёюя";
 
// эта функция делит string на слова и пихает их в vector string'ов. потом возвращает его
std::vector<std::string> split(const std::string& s, std::string delim) // s - передаваемый string объект, delim - знаки, которые делят string объект на слова
{
    std::vector<std::string> words; // вектор слов
 
    std::size_t prev = 0, found = s.find_first_of(delim); // позиции, где found - первое появление delim в s
 
    while (found != std::string::npos) // пока можем найти delim в передаваемом string объекте
    { 
        std::string temp_word(s, prev, found - prev); //создаем слово, которое берется из s, от предыдущей остановки копируем (found - prev) символов
 
        if (found - prev > 1) // если расстояние между найденной позицией delim и предыдущей позицие больше 1
            words.push_back(temp_word); // пихаем в вектор слов наше слово
 
        prev = found; // пердыдущая позиция равна последнему найденному знаку из delim
        found = s.find_first_of(delim, prev+1); // ищем снова delim в передаваемом string объекте
    }
 
    return words; // возвращаем вектор слов
}
 
int main() {
    setlocale(LC_ALL, ""); // кириллица
 
    std::string text = "Текст... с ,       разными!! словами, а так же с разными , знаками    !  пунктуации!"; // сам текст
 
    std::vector<std::string> words = split(text, " .,!"); // ищем из текста слова, разделяя их вторым аргументом
 
    // смотрим каждое слово, а точнее его последнюю букву
    for (int i = 0; i < words.size(); i++) 
    {
        for (int k = 0; k < 10; k++)
        {
            if (words[i].back() == gl[k]) // если последняя буква равна k'ному элементу массива гласных букв, то
            { 
                words.erase(words.begin() + i); i--; // удаляем из вектора слов элемент и индексом i, а i уменьшаем (потому что из вектора слов удалили элемент)
            }
 
        }
    }
 
    // очищаем текст
    text.clear();
 
    // каждое слово из вектора слов в текст запихаем
    for (int i = 0; i < words.size(); i++) {
        for (int j = 0; j < words[i].size(); j++)
            text.push_back(words[i][j]); // j'тая буква из i'того слова из вектора слов пихается в текст
    }
 
    std::cout << text << "\n\n"; // печатаем новый текст
 
    std::cin.get(); // держим консоль на месте
}
Может быть, чего-то намудрил (что вряд ли, там все достаточно просто), но код очень даже стабильный.

Добавлено через 23 секунды
Там большая часть кода - деление строки на слова.
0
Геомеханик
785 / 592 / 937
Регистрация: 26.06.2015
Сообщений: 1,409
24.04.2016, 22:49 #5
Лучший ответ Сообщение было отмечено zlodeyxgm как решение

Решение

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <cctype>
#include <cstring>
#include <locale.h>
#define is_delim(c)  (isalpha((c)) || (c) == '-')
typedef unsigned char uchar;
 
char* str_remove(char* s){
    const char vs[] = "ауоыиэяюёе";
    char*  t = s;
    uchar* q, *p, *i = (uchar*)s;
 
    for(p = i; *i; *i = *p){
        if(is_delim(*p)){
            for(q = p; is_delim(*q); ++q)
                ;
        
            if(strchr(vs, tolower(*(q - 1))) != NULL)
                p = q;
            else {
                while(p != q)
                    *i++ = *p++;
            }
            continue;
        } else
            ++i;
        ++p;
    }
    return t;
}
 
int main(void){
    setlocale(LC_ALL, "Rus");
 
    char s[] = "Начал пытаться продумывать решение сам и пришел к чему то такому: (просто наброски)";
    std::cout << s << std::endl;
    str_remove(s);
    std::cout << s << std::endl;
    return 0;
}
1
24.04.2016, 22:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.04.2016, 22:49
Привет! Вот еще темы с решениями:

Вывести все слова заканчивающиеся на букву "а" (переделать на dev c++)
Суть программы: Вывести все слова заканчивающиеся на букву &quot;а&quot;. #include...

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

Удалить среднюю букву из самого длинного слова и напечатать все слова на экран
Дано предложение. Напечатать все его слова, предварительно преобразовав каждое...

Из каждого слова заданного текста удалить последнюю букву.
Привет все, помогите с задачей: Из каждого слова заданного текста удалить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru