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

  • Автор темы DjCrazy
  • Дата начала
Статус
Закрыто для дальнейших ответов.
D

DjCrazy

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

domny

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

DarkKnight

Well-known member
01.08.2010
653
0
#3
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;
}
*/

}
 
D

DjCrazy

#4
Код:
#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
и еще один вопрос, вот програмка которая уже считает слова, правда не учитывая что разные считает количество символов и вконце выводит слова в которых нету двойных букв, правда странно то, что со слов в которых есть двойные буквы она выводит первые буквы, скажите что не так в коде
Код:
#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++;
}
}
 
D

DjCrazy

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

DarkKnight

Well-known member
01.08.2010
653
0
#6
шикарно, а вместо 65 использовать 'A' нельзя? или задача максимально запутать программу. Если надо будет поправить вы полезете в таблицу ASCII. и под DOS таблица .866 там русские буквы с 128, вам нетрудно переписать программу в случае чего?)
OemToCharA(str,str); //Переведем строку в Ansi для совпадения кодов
Вот эта строка говорит об однозначности кодировки....

Алгоритм очень сложный, да и вообще, я бы не выделял слова в массив.
Вообще то программа подразумевает конечную работу со словами (слово - конечное подразумевает то что манипуляции происходят уже со словами, а не со строкой)
А алгоритм не сложный - а наглядный, прекрасно видна именно работа со строковыми функциями, их структура и принцип работы..
Добавлено: и кроме того:

Цитата:




нужно подсчитать количество разных слов которые разделены




ключевое слово разных не вижу где у вас проверка на уникальность слова в строке.
Я слово "разных" - не заметил.... И кстати опять же сам себе противоречишь?!
Если разных слов кол-во найти нужно??? Нужно ли хранилище??? (массив в данном случае)
2.Оставшуюся часть строки передаешь в strstr :strstr(&s[i+L+1],word); как то так должно работать
Разделители любые, так что это не вариант, "дом" "домовой" - разные слова как не крути... А ты сразу же скажешь - что слова не уникальны...

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

DarkKnight

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

счиать количество символов текущего слова и писать:
buffer[cnt++]=str[j];
не проще?
И что мы получим??? Как вы по коду видели память я не обнуляю, выделяю ее динамически... А вы предлагаете завершающий символ строки перезаписать, вам не кажется, что это по меньшей мере - не правельно.... И благо, если в 128 байтах буфера хот раз встретить 0, а если нет????(!!!)
подробнее читай выше. Такие заморочки для большей наглядности алгоритма?
по поводу строковых функций у вас лишь strcat,strlen,strcpy, хотя смысла использовать их если по заданию требуется найти не повторяющиеся слова (ключевое слово найти), ИМХо логичнее все же использовать strstr.
К меня основная часть строковых функций (исходя из логики алгоритмических языков) - это копирование, измерения длины и объединение, все остальные являются всего лишь вытекающими из них...
Хорошо, вы советуете, использовать strstr, а так же советуете проверять от текущего слова строку далее... Отбросим все разделите, и прочию ахинею...
У вас строка "Я пришел. Я ушел." Смотрим... Букв 'Я' - в словах нет, как хорошо, вхождений субстроки в лишних словах не будет... Но если при первом "Я"- уникальность действительно будет нарушена, то простите на втором Я, вхождение уже не будет найдено - ваш способ выдаст уникальность этого "Я"...
 

DarkKnight

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


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

DarkKnight

Well-known member
01.08.2010
653
0
#9
в buffer получим выделенное из строки слово, в cnt получим количество букв в этом слове.
А конец bufferа мы у дедушки на деревне получим? даже strlen(buffer) в этом варианте явно не длину слова выдаст
а там более strstr потом это дело передовать...

Все правильно, слово "Я" будет посчитано только 1 раз. По заданию требуется найти "количество разных слов", а не количество слов, встречающихся 1 раз.
Согласен, в этом месте был не прав, просто вот это ваша строка была дословно воспринита....
не вижу где у вас проверка на уникальность слова в строке.
 
Статус
Закрыто для дальнейших ответов.