Программа для подсчета слов

Тема в разделе "C/C++/C#", создана пользователем DjCrazy, 22 окт 2010.

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

    DjCrazy Гость

    В универе есть задания, сделал все кроме одного, нужно подсчитать количество разных слов которые разделены между собой символами. я знаю как начать, но не знаю как именно сделать что б подсчитовались слова, и еще после того нужно вывести на экран слова в которых нету двойных букв.язык программирования C.
     
  2. domny

    domny Гость

    Могу написать программу с нуля за деньги. Если интересует - сучите 648964446.
     
  3. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    Код (C++):
    #include <iostream>
    #include <Windows.h>
    using namespace std;

    //Функция определения повторяющихся символов в строке
    bool NotDoubleChar(char *str)
    {
    for (int i = 0; i<strlen(str);i++) //Обходим все символы строки
    {
    for (int j = i+1; j<strlen(str);j++) //Обходим все символы строки идущие после текущего (прошлый цикл)
    {
    if (str[i] == str[j]) //найден повторяющийся символ
    return false; //Вернем False есть повторяющиеся символы
    }
    }
    return true; //Вернем ТРУ если нет ни одной повторяющейся буквы
    }

    void main(void)
    {
    setlocale(LC_ALL,"Russian"); //Локаль Для консоли под Win32, что бы кириллица нормально отображалась
    //для начала проведем анализ алфавита и его кодов (unsigned char)
    //(65-90) - заглавные латинские буквы
    //(97-122) - строчные латинские буквы
    //(192-255) - наши буквы
    char str[4098];
    cout<<"Введите пожалуйста строку :"<<endl;
    gets(str);

    OemToCharA(str,str); //Переведем строку в Ansi для совпадения кодов

    //динамический массив мне определять обламывает, поэтому обойдемся статикой
    char Slova[128][4098]; //Максимальная длина слова 127 символов, максимальное кол-во слов 4098
    int Chet = 0; //Счетчик слов

    char *buffer = new char[128]; //Буферная строка
    buffer[0]='\0'; //Определим завершающий символ в ней
    Slova[0][Chet]='\0'; //Определим завершающий символ строки в массиве строк

    for (int j=0; j<=strlen(str);j++) //Обходим всю строку посимвольно
    {
    //Если символ принадлежит букве
    if ( ((unsigned char)str[j]>=65 && (unsigned char)str[j]<=90) || ((unsigned char)str[j]>=97 && (unsigned char)str[j]<=122) || ((unsigned char)str[j]>=192 && (unsigned char)str[j]<=255) )
    {
    char b2[2]; b2[0]=str[j];b2[1]='\0'; //Запишим его в переменную типа строка (НАШ_СИМВОЛ,СИМВОЛ_ЗАВЕРШЕНИЯ_СТРОКИ)
    strcat(buffer,b2); //Объеденим строки
    }
    else //Если символ не является буквой
    {
    strcpy(Slova[Chet],buffer); //Скопируем буфер в наш массив строк
    Chet++; //Увеличим счетчик слов
    delete[] buffer; //Отчистим выделеную память под буфер
    buffer = new char[128]; //Выделим новую память
    buffer[0]='\0'; //Поставим завершающие символы строки (!!!)Кстати, если не понятно зачем я это делаю, расскажу, все строковые функции работают отталки
    Slova[0][Chet]='\0'; //ваясь от завершающего символа '\0' так что это обязательно нужно делать, иначе ф-ии strcat, strlen,strcpy - будут выдавать охинею
    }                       //Вернее они будут обрабатывать память идущую долеко после конца строки

    }
    //Теперь все наши слова содержатся в массиве Slova[Chet]; Chet - кол-во слов
    cout<<endl<<"Кол-во слов :"<<Chet;

    //Теперь про повторябщиеся буквы в словах
    cout<<endl<<"Слова с повторяющимися символами :"<<endl;
    for (int i=0; i<Chet; i++) //Обойдем весь массив слов
    {
    if (!NotDoubleChar(Slova[i]))
    {
    cout<<Slova[i]<<endl;
    }
    }


    system("pause");

    /*
    //Таблица кодов символов
    for (int i =0; i<256;i++)
    {
    cout<<i<<": "<<(unsigned char)i<<endl;
    }
    */


    }
     
  4. DjCrazy

    DjCrazy Гость

    Код (Text):
    #include <stdio.h>
    void main () {
    char a[32767],b[32767];
    int sch1=0,i,j,z,k,x,c,sch11;
    gets(a);
    for(i=0;a[i]!='\0';i=++j){
    z=a[i];
    k=0;
    for(j=i;(z>64&&z<91)||(z>96&&z<123)||(z>127&&z<176)||(z>223&&z<146);j++){
    b[k]=a[j];//perenos slova vo vtoroi masiv
    k++;
    z=a[j+1];
    }
    b[++k]='\0';//posle slova terminator
    sch11=0;
    for(x=j;a[j]!='\0';x=x){
    z=a[x];
    c=0;
    for(x++;(z>64&&z<91)||(z>96&&z<123)||(z>127&&z<176)||(z>223&&z<146);x++){
    if(b[c]==a[x])
    c++;
    z=a[x+1];
    }
    if(c==k)
    sch11++;
    }
    if(sch11>0)
    sch1--;
    }
    printf("%d",sch1);
    }
    вот я пробую делать это програмка вот что делает, если слово которое я взял повторяется хоть раз, то оно его отнимает от общей сумы слов, но она почемуто не работает, помогите если кто сможет, как слова посчитать я уже знаю, а вот разные слова должна эта програмка считать, но в ней чтото не так с переменной k
    и еще один вопрос, вот програмка которая уже считает слова, правда не учитывая что разные считает количество символов и вконце выводит слова в которых нету двойных букв, правда странно то, что со слов в которых есть двойные буквы она выводит первые буквы, скажите что не так в коде
    Код (Text):
    #include <stdio.h>
    void main () {
    char a[1000],b[100];
    int sch1=0,sch2=0,q,w,i,j,k,e;
    gets(a);
    for(i=0;a[i]!='\0';i++){
    q=a[i];
    if((q>0&&q<48&&q!=32)||(q>57&&q<65)||(q>90&&q<97)||(q>122&&q<128)||(q>175&&q<224)||(q>245&&q<255))
    sch2++;
    }
    for(i=0;a[i]!='\0';i++){
    q=a[i];
    w=a[i+1];
    if((q>0&&q<48)||(q>57&&q<65)||(q>90&&q<97)||(q>122&&q<128)||(q>175&&q<224)||(q>245&&q<255)){
    if((w>0&&w<48)||(w>57&&w<65)||(w>90&&w<97)||(w>122&&w<128)||(w>175&&w<224)||(w>245&&w<255))
    printf("");
    else
    sch1++;
    }
    }
    i--;
    q=a[0];
    w=a[i];
    if((q>0&&q<48)||(q>57&&q<65)||(q>90&&q<97)||(q>122&&q<128)||(q>175&&q<224)||(q>245&&q<255))
    sch1--;
    if((w>0&&w<48)||(w>57&&w<65)||(w>90&&w<97)||(w>122&&w<128)||(w>175&&w<224)||(w>245&&w<255))
    printf("");
    else
    sch1++;
    printf("slova %d; symvoly %d",sch1,sch2);
    //==============================================================================
    =
    for(i=0;a[i]!='\0';i=j-1){  //начиная отсюда програмка определяет слова в которых нету двойных букв и выводит на экран
    k=0;
    q=a[i];
    for(j=j;(q>47&&q<58)||(q>64&&q<91)||(q>96&&q<123)||(q>127&&q<176)||(q>223&&q<246);j++){
    b[k]=a[j];
    q=a[j+1];
    k++;
    }
    b[k]='\0';
    e=0;
    for(w=0;b[w]!='\0';w++){
    if(b[w]==b[w+1])
    e++;
    }
    if(e==0)
    for(w=0;b[w]!='\0';w++)
    printf("%c",b[w]);
    printf("%c",a[j]);
    j++;
    }
    }
     
  5. DjCrazy

    DjCrazy Гость

    это я понял, но то что я написал выше должно работать,только вот гдето в нем ошибка, а где не могу понять и во втором коде подскажите в чем проблемка???
     
  6. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    OemToCharA(str,str); //Переведем строку в Ansi для совпадения кодов
    Вот эта строка говорит об однозначности кодировки....

    Вообще то программа подразумевает конечную работу со словами (слово - конечное подразумевает то что манипуляции происходят уже со словами, а не со строкой)
    А алгоритм не сложный - а наглядный, прекрасно видна именно работа со строковыми функциями, их структура и принцип работы..
    Я слово "разных" - не заметил.... И кстати опять же сам себе противоречишь?!
    Если разных слов кол-во найти нужно??? Нужно ли хранилище??? (массив в данном случае)
    Разделители любые, так что это не вариант, "дом" "домовой" - разные слова как не крути... А ты сразу же скажешь - что слова не уникальны...

    И не всегда , для человека который хочет понять принцип работы, хорошо короткие алгоритмы, где сплошные указалели, инкрементирование и дек. указателей, сплошные ссылки и пробежки по памяти от одного конца в другой.... Не спорю, быстро, удобно... Но каши в голове от этого меньше не станет...
    Хотя это лично мое ИМХО...
     
  7. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    Я прекрасно понял о чем вы говорили, в своем посте... Использование isspace(), ispunct() или еще проще isalnum (если исходить от противного по вашему методу), затрудняют логику и понимание.... Подумайте сами, данный раздел форума носит в первую очередь педогогическую функцию... И человеку, куда нужнее понять, как в C++ хранятся строки типа char*, как компилятор инициализирует или определяет конец строки или как хранит строку всего с одним символом... Как не делает разницы между типами char-вроде бы символьным, и int... Как свободно преобразуется в целочисленную последовательность кодов русское слово...
    Смысл написание программ в этом разделе, по моему мнению, это затрагивание того материала, который уже знает автор прозьбы.... И написание как можно более понятного для него кода... А писать фразы, типо, обойти элементы массива лучше p++; (когда p - указатель на него); или ключевое слов, поверьте я тоже не плохо могу... Но когда подход написания я выбираю не для оптимизации или сужения кода, к критике подхожу резко...

    И что мы получим??? Как вы по коду видели память я не обнуляю, выделяю ее динамически... А вы предлагаете завершающий символ строки перезаписать, вам не кажется, что это по меньшей мере - не правельно.... И благо, если в 128 байтах буфера хот раз встретить 0, а если нет????(!!!)
    К меня основная часть строковых функций (исходя из логики алгоритмических языков) - это копирование, измерения длины и объединение, все остальные являются всего лишь вытекающими из них...
    Хорошо, вы советуете, использовать strstr, а так же советуете проверять от текущего слова строку далее... Отбросим все разделите, и прочию ахинею...
    У вас строка "Я пришел. Я ушел." Смотрим... Букв 'Я' - в словах нет, как хорошо, вхождений субстроки в лишних словах не будет... Но если при первом "Я"- уникальность действительно будет нарушена, то простите на втором Я, вхождение уже не будет найдено - ваш способ выдаст уникальность этого "Я"...
     
  8. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    Я думаю из приведенного мной выше текста, Вам не составит труда убедить себя, что вы неправы практически по всех приведенным вами пунктам, за исключением привязанности к кодироки и букву "Ё", с этим я с Вами полностью согласен, но еще раз уточнюсь, что это для более активного и простого понимания процессов работы со строками.. А букву Ё - я просто не использую, как и 80%ов пользователей клавиатуры, и поверьте слово "Ёжик", они совершенно не думают писать как какой-нибудь "йежик", просто на автоматие пишут его "ежик" (и кстати ни у кого вопросов не возникает насчет этого)...
    Считайте, что в данном примере клавиша находящиеся ниже ESCпа просто разделитель.
    А про уникальность я просто просмотрел... И в моем примере никто не помешает пройтись по всему циклу, и вложеным циклом проверить эту уникальность...


    Добавлено: А так же любые манипуляции с этими словами, без изменения основного кода...
     
  9. DarkKnight

    DarkKnight Well-Known Member
    C\C++ Team

    Регистрация:
    1 авг 2010
    Сообщения:
    653
    Симпатии:
    0
    А конец bufferа мы у дедушки на деревне получим? даже strlen(buffer) в этом варианте явно не длину слова выдаст
    а там более strstr потом это дело передовать...

    Согласен, в этом месте был не прав, просто вот это ваша строка была дословно воспринита....
     
Загрузка...
Статус темы:
Закрыта.

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