Поиск в тексте символов (c++)

Тема в разделе "Общие вопросы по С и С++", создана пользователем o1ps, 27 сен 2007.

Статус темы:
Закрыта.
  1. o1ps

    o1ps Гость

    Возникла задача : Задан текст, состоящий из слов, записанных через запятые, и заканчивающийся точкой.
    Длина текста не больше 150 символов, могут быть использованы любые символы. Словом
    считается после-довательность символов, не содержащая пробел. Сформировать строку из
    5-символьных слов, несо-держащих букву s. Получить массив кубов цифровых слов.


    Вот код, который мне удалось реализовать:
    Код (Text):
    //#include "stdafx.h"
    #include <stdlib.h>
    // для функции exit()

    #include <string.h>
    #include <iostream.h>
    #include <cstdio>
    // для функций работы с файлами

    void main(void) {
    char
    text[149],  // загруженный из файла текст

    *_word, // рабочая переменная для корректного
    // разделения строки на слова

    **words,    // здесь будут храниться все слова из строки

    fourSW[150], // в этом массиве будут храниться слова длиной в 4
    // символа, содержащие буквы и цифры

    **repeatWord;
    // этот массив будет содержать повторяющиеся слова

    words = new char*[150];
    repeatWord = new char*[150];

    int
    i,  //
    j,  // счётчики циклов
    k,  //

    word=0,     // количество слов в загруженной строке

    lengths[150],       // длины каждого слова

    digitPos=0,     // рабочая переменная, которая будет содержать
    // информацию о словах содержащих цифры

    repeat[150],        // количество повторений для каждого слова

    squares[150][3],    // кубы цифровых слов

    sq=0,           // количество цифровых слов

    repeats=0;      // общее количество различных слов в тексте

    FILE *fp;   // указатель на дескриптор файла

    /* Нижеследующие переменные созданы для показа умения работы со строковыми функциями */
    char text1[9]="Proverka";
    char text2[10]="Propil'on";
    char *p;

    if ((fp = fopen("data.txt", "r")) == NULL) goto fileNotExists;
    // открываем файл, если не удаётся - уходим в ошибку

    fread(&text, sizeof(char), 150, fp);
    cout << "Loaded text: " << text << endl << endl;
    fclose(fp);
    // читаем из файла 150 символов, выводим текст, закрываем файл

    /* следующий блок делит считанную строку на массив слов, с которым
    гораздо удобнее работать */
    do {
    if (word==0) {
    _word = strtok(text, ",");
    } else {
    _word = strtok(NULL, ",");
    }   // для определения каждого последующего слова используется
    // функция strtok()

    if (_word == NULL) break;

    word++;
    words[word] = new char[strlen(_word)];
    words[word] = _word;
    lengths[word] = strlen(_word);
    // заносим слово в массив words[], а его длину - в lengths[]
    } while (1);

    cout << endl << "Words (length = 5) with digits and characters:" << endl;

    strcpy(fourSW, "");
    /* следующий блок кода найдёт все слова, содержащие и буквы и цифры,
    и не имеющие при себе буквы s */
    for (i=1; i<=word; i++) {
    digitPos=strcspn(words[i], "s");
    // ищем, на какой позиции встречается буква в слове
    if (atoi(words[i])==0 && digitPos>0 && digitPos!=lengths[i] && lengths[i]==4) {
    strcat(fourSW, words[i]);
    strcat(fourSW, ", ");
    }
    }
    cout << fourSW << endl << endl;
    // выводим найденное

    /* следующие блок кода ищет все повторяющиеся слова в тексте */
    for(i=1; i<=word; i++) {
    for(j=i; j<=word; j++) {
    if (words[i]==words[j]) {
    for(k=1; k<=repeats; k++) {
    if (0==strcmp(words[i], repeatWord[k])) {
    repeat[k]++;
    goto n1;
    }
    }
    repeats++;
    repeatWord[repeats] = new char[lengths[i]];
    repeatWord[repeats]=strdup(words[i]);
    repeat[repeats]=1;
    }
    }
    }

    n1:
    cout << "Repeat words: " << endl;
    for (i=1; i<=repeats; i++)
    if (repeat[i]>1)
    cout << repeatWord[i] << " [" << repeat[i] << "], ";
    // выводим слова, у которых количество повторений больше единицы

    /* следующий блок кода находит цифровые слова и выводит их кубы */
    cout << endl << endl << "Numeric words, and its squares: " << endl;

    for (i=1; i<=word; i++) {
    for(int j=0; j<lengths[i]; j++)
    if (atoi(&words[i][j])==0 && words[i][j]!='0') goto n2;

    sq++;
    squares[sq][1]=atoi(words[i]);
    squares[sq][2]=(atoi(words[i])*atoi(words[i])*atoi(words[i]));
    n2:
    cout << "";
    }

    for (i=1; i<=sq; i++)
    cout << "Number: " << squares[i][1] << "; square: " << squares[i][2] << endl;

    cout << endl << "------------------------------------------" << endl << endl;

    // весь остальной код показывает умение работать со строковыми функциями

    cout << "text1='" << text1 << "';" << endl;
    cout << "text2='" << text2 << "';" << endl;

    p=strstr(text1, "ov");

    cout << "strcmp(text1, text2) = '" << strcmp(text1, text2) << "'" << endl;
    cout << "strncmp(text1, text2, 3) = '" << strncmp(text1, text2, 3) << "'" << endl;
    cout << "strlwr(text1) = '" << strlwr(text1) << "'" << endl;
    cout << "strupr(text2) = '" << strupr(text2) << "'" << endl;
    strrev(text1);  // функция заменяет строку
    cout << "strrev(text1) = '" << text1 << "'" << endl;
    strrev(text1);// возвращаем строку после вывода в исходное состояние
    cout << "strspn(text2, 'ORP') = '" << strspn(text2, "ORP") << "'" << endl;
    cout << "strstr(text1, 'rk') = '" << p << "'" << endl;
    cout << "strchr(text1, 'r') = '" << strchr(text1, 'r') << "'" << endl;
    cout << "strrchr(text1, 'r') = '" << strrchr(text1, 'r') << "'" << endl;

    fp=fopen("output.txt", "w");
    for(i=1; i<word; i++) {
    fwrite(words[i], sizeof(char), lengths[i], fp);
    fputs(", ", fp);
    }
    fclose(fp);

    // удаляем все переменные, что мы использовали в процессе
    delete repeatWord, repeats, text1, text2, text, _word, fourSW, words, lengths, digitPos, squares, sq, repeat, fp;

    exit(0);

    fileNotExists:
    cout << "File with input data not found" << endl;
    }

    Не получается найти слова, не содержащие "S". Подскажите пожалуйста, будьте любезы, как доделать код для нормальной реализации данной задачи.
    Буду очень признателен.
     
  2. grigsoft

    grigsoft Well-Known Member

    Регистрация:
    15 ноя 2005
    Сообщения:
    735
    Симпатии:
    0
    Код вставленный специально для показа умения работать со строковыми функциями - это мило. Жаль только весь остальной код это старательно опровергает.
    Отвечая на вопрос - strchr тебя спасет с буквой S.
    Замечания (можно не читать, если ты не будущий программист, а филолог выполняющий задание по информатике).
    1. Сваленный в кучу код в main, в результате - goto. Все это должно быть разбито на небольшие функции и красиво записано.
    2. Переменные должны всегда обнуляться при определении.
    3. Чтение 150 символов в буфер длиной 149.
    4. Что это?
    Код (Text):
    words[word] = new char[strlen(_word)];
    words[word] = _word;
    А вот это?
    Код (Text):
    repeatWord[repeats] = new char[lengths[i]];
    repeatWord[repeats]=strdup(words[i]);
    И вот это?
    Код (Text):
    if (words[i]==words[j])
    Явно стоит перечитать главу о работе со строками в С\С++.

    5. Лень проверять, но кажется мне что atoi("21год") нормально вернет тебе 21. В любом случае atoi("год") == atoi("000"), так что не стоит ее использовать для поиска цифровых слов. strtol в лучшем случае.

    И это не вдаваясь в своеобразный цикл поиска повторных слов и глубины алгоритмов - только то что глаз режет.
     
  3. o1ps

    o1ps Гость

    заменил
    Код (Text):
    if ((fp = fopen("data.txt", "r")) == NULL)
    {
    cout << "File with input data not found" << endl;
    //  getch();
    exit(0);
    }
    По поводу поиска слов без "s" переделал цикл:
    Код (Text):
    for (i=1; i<=word; i++) {
    if(strstr(words[i], "s")==NULL)
    {
    strcat(fourSW, words[i]);
    strcat(fourSW, ", ");
    }
    }
    Но вопрос - выводит все слова без "s". Подскажите пожалуйста как точно организовать цикл по подсчету количества символов, ибо необходимы только слова 5-символьной длины.
    Буду очень признателен.
     
  4. Pasha

    Pasha Гость

    Для: o1ps
    Цикл по подсчету количества символов? strlen.
     
  5. o1ps

    o1ps Гость

    Код (Text):
    if(strstr(words[i], "s")==NULL)
    if(strstr(words[i], "s")==NULL))
    if (strlen(words[i], "s")==5)
    ??
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей