1

Тема: Тестовий рядок

Добрий вечір!
Стикнулася з проблемою при обробці текстових рядків..
Маю завдання: В рядку, що вводить користувач, знайти кількість слів, які містять однакову кількість голосних і приголосних літер, вивести на екран найдовше слово та видалити з тексту всі слова-паліндроми.
Кількість слів з однаковою кількістю голосних та приголосних букв знайшла. Не розумію, де помилка в реалізації другого пункту щодо найдовшого слова (виводить постійно лише перше слово рядка), а як видалити слова-паліндроми, якщо чесно, взагалі не розумію до кінця. Буду дуже рада будь-якій допомозі чи підказці)
Мій код:

#include "StdAfx.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream> 
#include <conio.h> 
#include <string.h>
#include <string>
#define MAX 25
using namespace std;
int main()
{
    char str[100], copystr[100], maxword[20], *word=0, *max_word = 0;
    int i, d, kol=0, k=0, kol1=0, kolsl=0, f=0, maxlen=0, mass[MAX]={0}, mass1[MAX]={0},mass2[MAX]={0}, j=0, len, maxsize =0, max=0, length;
    bool f_yes, t;
    string words[100], words1;
    char *p; 
    /*Визначення кількості слів, які містять однакову кількість голосних та приголосних букв*/
    puts("You can perform a specific operation on a text string!");
    puts("Enter the line:");
    gets_s(str);                                       
    p = strtok(str, " ,.!?-0123456789:;");
    while(p!=0)
    {
        for (i = 0; i < strlen(p); i++)
        {
            if (p[i] == 'A' || p[i] == 'a' || p[i] == 'O' || p[i] == 'o' || p[i] == 'I'|| p[i] == 'i'|| p[i] == 'E'|| p[i] == 'e'|| p[i] == 'U'|| p[i] == 'u')    
                mass[j]++;        
            else 
                mass1[j]++;         
        }       
        p = strtok(NULL, " ,.!?-0123456789:;");
        j++;
    }      
    setlocale(LC_CTYPE, "ukr");
    for(i=0; i<j;i++)
    {
        printf("Word %i:\nCounts of vowels:%i\tCounts of consonants:%i\n",i+1, mass[i], mass1[i]);    
        if (mass[i] == mass1[i])
            k++;
    }
    printf("Counts of words that contain the same counts of vowels and consonants: %i\n",  k);                              
    /*Визначення найдовшого слова у рядку*/
    length=strlen(p);
    while(p!=NULL) 
    {
        length=strlen(p);
        if(maxlen < length) 
        {
            maxlen = length;
            word=p;
        }
        p = strtok(NULL, " ,.!?-0123456789:;");
    }
    printf("Maxword is '%s' and the length of the word is equal to %2d\n", word, maxlen);
    /*Пробувала визначити слова-паліндроми для видалення*/
    len = words1.length();
    while(p!=0)
    {
        for(int i = 0; i < len/2; ++i)
        {
            if(words1[i] != words1[len-i-1])
            {
                words1[i]=mass2[j];
            }
        }
        p = strtok(NULL, " ,.!?");
        j++;
    }
    /*for(i=0; i<j; i++)
        cout<<"Mass: "<<mass2[i]<<endl;*/
    _getch();
    system("pause");
    return 0;
}
Подякували: koala1

2

Re: Тестовий рядок

не бачу жодної функції. цю кашу їж сама. і з мовою визначся, бо так не роблять. або с, або с++

3

Re: Тестовий рядок

Akos_Bond написав:

Буду дуже рада будь-якій допомозі чи підказці)

Перше і, напевно, єдине, що я можу вам порадити, то це визначитись якою мовою ви пишете С чи С++?
Бо те, що ви робите, можна описати лише одним словом - каша.

4

Re: Тестовий рядок

Так, я це розумію. Але, наприклад, функції використовувати мені ще не можна, бо програму просто не врахують як правильно зроблену. А щодо визначення С чи С++ я зрозуміла. Дякую

5

Re: Тестовий рядок

Akos_Bond написав:

Так, я це розумію. Але, наприклад, функції використовувати мені ще не можна, бо програму просто не врахують як правильно зроблену. А щодо визначення С чи С++ я зрозуміла. Дякую

Ну, функції ви й так використовуєте, такі як strtok, printf та інші :)
Ваша проблема не у відсутності функцій, а у тому, що ви пишете у стилі С89, де ще змінні не можна було визначати безпосередньо у циклі for, тому майже всі змінні були "глобальні". Проте на дворі вже 2020 рік. Ну і так, не змішуйте С та С++, для початківців це дуже погана практика.

Подякували: koala, leofun012

6

Re: Тестовий рядок

Дякую, про стиль запам'ятаю. Можете мені пояснити саму суть. Мені цікаво, чому другий підпункт щодо найдовшого слова працює некоректно. І хотілося б дізнатися, як можна видалити слова-паліндроми.

7

Re: Тестовий рядок

Akos_Bond написав:

В рядку, що вводить користувач, знайти кількість слів

Для початку, було б непогано визначити "слово". Це дещо нетривіальна задача; бачу, ви використовуєте визначення "послідовність символів, що не містяться у стрічці " ,.!?-0123456789:;". Звісно, це ваше право вважати "привіт(світ)" одним словом, а "веб-сайт" чи "convert2byte" - двома, але це треба якось зазначати. Можу точно сказати, що ваше рішення далеко не найгірше з тих, які я бачив. Я б брав тупо пробіли-розділювачі.
Ви не зовсім зрозуміло називаєте змінні. mass та mass1? Я за назвами нічого не можу сказати, що це. wovels та consonants було б значно краще.
Ще є така дуже зручна функція, як strchr, яку (дещо неочевидно, погоджуюся) використовують у подібних випадках. Порівняйте

if (p[i] == 'A' || p[i] == 'a' || p[i] == 'O' || p[i] == 'o' || p[i] == 'I'|| p[i] == 'i'|| p[i] == 'E'|| p[i] == 'e'|| p[i] == 'U'|| p[i] == 'u')   

З

if(strchr("AaEeIiOoUu", p[i])!=nullptr)

що робить те саме. За бажання можна навіть написати

if(strchr("aeiou", tolower(p[i])))

якщо підключити <cctype>, але то вже питання смаку.

Akos_Bond написав:

виводить постійно лише перше слово рядка

Проблема в тому, що strtok ріже стрічку на шматки, розставляючи там нульові символи. Тобто після першого циклу ви вже матимете не введену користувачем стрічку str, а, фактично, перше слово (в масиві після нього будуть ще символи, але функції для роботи зі стрічками розглядають символи лише до '\0'). Тобто перед використанням strtok треба скопіювати стрічку в іншу змінну і працювати вже з нею, а коли знову знадобиться початкова стрічка - брати знову її.

Akos_Bond написав:

а як видалити слова-паліндроми, якщо чесно, взагалі не розумію

Для початку - "видалити" - це з погляду користувача. З погляду програміста це "скопіювати все, крім слів-паліндромів, у нову стрічку". Тут, щоправда, знову втручається визначення слова. Якщо видалити паліндроми з "ab, bab, cd", то в результаті має вийти "ab, cd" чи "ab, , cd"? Знову ж таки, можна підійти з різних боків, треба лише вирішити, як.

Якщо ж є стрічка з окремим словом, то визначити, чи є воно паліндромом, дуже просто:

char word[10]="palilap";//припустимо
int len = strlen(word);
bool is_palindrom=true; //поки що припускаємо, що це паліндром
for(int i=0,j=len-1;i<j;++i,--j) //ідемо по слову з двох боків до середини
    if(tolower(word[i])!=tolower(word[j])){ //якщо літери різні
        is_palindrom=false; //то це не паліндром
        break; //і виходимо з циклу, далі немає сенсу перевіряти
    }
if(is_palindrom){//якщо змінна лишилася true, то це паліндром...

Звісно, цю перевірку краще загорнути в функцію.

Ну і якось визначайтеся, з якою мовою ви працюєте. Якщо це C, то у вас зайві заголовки з C++ (вони в будь-якому разі зайві, ви їх не використовуєте); а якщо C++, то, відповідно, з C (і функції звідти).

Подякували: Akos_Bond, wander, leofun013

8

Re: Тестовий рядок

Akos_Bond написав:

Мені цікаво, чому другий підпункт щодо найдовшого слова працює некоректно.

Дивіться на ваш магічний вказівник р і на що в цей момент він вказує. У вашому випадку, він вказує на результат роботи strtok і має бути рівним null.

Подякували: Akos_Bond, koala2

9

Re: Тестовий рядок

ur_naz написав:

не бачу жодної функції. цю кашу їж сама. і з мовою визначся, бо так не роблять. або с, або с++

В коледжі нас вчать С++ за методичками і лекціями С))

10

Re: Тестовий рядок

grinyuk309 написав:

В коледжі нас вчать С++ за методичками і лекціями С))

Це як так?
Літературу рекомендують по мові С, а вимагають кодити на плюсах?
Ви точно на лекціях все вірно зрозуміли?

11

Re: Тестовий рядок

Droid 77 написав:
grinyuk309 написав:

В коледжі нас вчать С++ за методичками і лекціями С))

Це як так?
Літературу рекомендують по мові С, а вимагають кодити на плюсах?
Ви точно на лекціях все вірно зрозуміли?

а чому ви дивуєтесь? ми, на першому курсі взагалі в BCPP код писали, наприклад
https://winworldpc.com/res/img/screenshots/30-34fa6e1775d9b8c9e0217326fd93582c-Borland%20CPP%203.1%20-%20DOS%20IDE.png

Подякували: koala1

12 Востаннє редагувалося wander (10.06.2020 19:12:36)

Re: Тестовий рядок

FakiNyan написав:

а чому ви дивуєтесь? ми, на першому курсі взагалі в BCPP код писали, наприклад

А, чому тут дивуватися? Це хоча б С++ компілятор, а його текстовий редактор з мінімально-необхідним набором функціоналу справлявся. Ну, а про те, що у нас все безбожно застаріло і так всі знають.

Подякували: FakiNyan1