#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
const int str_len=128;//максимальная длина строки
struct word//структура, описывающая слово
{
char *str;//сама строка
int count;//кол-во раз, встречаемых в тексте
word *next;//указатель на следующее слово в списке
word *prev;//указатель на предыдущее слово в списке
};
//поиск в списке заданного слова
//ф-ия возвращает указатель на найденный элемент списка или NULL, если элемент не найден
word* search_word(word *head, char str[str_len])
{
word *cur;
cur=head;
while (cur)
{
if (!strcmp(cur->str, str)) return cur;
cur=cur->next;
}
return NULL;
}
//добавление в список нового слова
void add_word(word *&head, char *new_word)
{
if (!head)//если список пустой, то создадим и заполним
{
head=new word;
head->str=new char[str_len];
strcpy(head->str, new_word);
head->count=1;
head->prev=NULL;
head->next=NULL;
}
else
{
word *cur;
cur=search_word(head, new_word);//ищем слово в списке
if (cur)//если слово уже есть
{
cur->count++;//то просто увеличиваем кол-во повторений слова в тексте
}
else//иначе добавляем слово в конец списка
{
cur=head;
while (cur->next) cur=cur->next;
cur->next=new word;
cur->next->str=new char[str_len];
strcpy(cur->next->str, new_word);
cur->next->count=1;
cur->next->next=NULL;
cur->next->prev=cur;
}
}
}
//удаление из конца строки символов .,:;?!()
char* remove_delims(const char *str)
{
char *res=new char[str_len];//результирующая строка
int i=strlen(str)-1;//узнаем индекс последнего символа
int j=0;//индекс символа в результирующей строке
//бежим по исходной строке с конца до первого непунктуационного символа
while (i>=0 && (str[i]=='.' || str[i]==',' || str[i]==';' || str[i]==':' || str[i]=='?' || str[i]=='!' || str[i]=='(' || str[i]==')')) i--;
while (j<=i)//все остальные символы исходной строки копируем в результирующую
{
res[j]=str[j];
j++;
}
res[j]='\0';//завершим строку
return res;
}
//создание списка слов с нечётным количеством букв из исходного
word* odd(word *all)
{
word *head=NULL;
word *cur1, *cur2;
cur1=all;
while (cur1)
{
if (strlen(cur1->str)%2!=0)//проверка на нечётность
{
if (!head)
{
head=new word;
head->str=new char[str_len];
strcpy(head->str, cur1->str);
head->count=cur1->count;
head->prev=NULL;
head->next=NULL;
cur2=head;
}
else
{
cur2->next=new word;
cur2->next->str=new char[str_len];
strcpy(cur2->next->str, cur1->str);
cur2->next->count=cur1->count;
cur2->next->prev=cur2;
cur2=cur2->next;
cur2->next=NULL;
}
}
cur1=cur1->next;
}
return head;
}
//сортировка слов в списке пузырьком
word* sort_words(word *a)
{
word *cur1, *cur2;
word *temp=new word;
temp->str=new char[str_len];
cur1=a;
while (cur1->next) cur1=cur1->next;
while (cur1!=a)
{
cur2=a;
while (cur2!=cur1)
{
if (strcmp(cur2->str, cur2->next->str)>0)
{
strcpy(temp->str, cur2->str);
temp->count=cur2->count;
strcpy(cur2->str, cur2->next->str);
cur2->count=cur2->next->count;
strcpy(cur2->next->str, temp->str);
cur2->next->count=temp->count;
}
cur2=cur2->next;
}
cur1=cur1->prev;
}
delete temp;
return a;
}
//создание списка из слов с гласной посередине
word* public_in_middle(word *odd)
{
word *head=NULL;
word *cur1, *cur2;
cur1=odd;
int middle;//индекс буквы в середине слова
while (cur1)
{
middle=strlen(cur1->str)/2;
if (cur1->str[middle]=='A' || cur1->str[middle]=='a'|| cur1->str[middle]=='E'|| cur1->str[middle]=='e'|| cur1->str[middle]=='I'|| cur1->str[middle]=='i'|| cur1->str[middle]=='O'|| cur1->str[middle]=='o'|| cur1->str[middle]=='U'|| cur1->str[middle]=='u'|| cur1->str[middle]=='Y'|| cur1->str[middle]=='y')
{
if (!head)
{
head=new word;
head->str=new char[str_len];
strcpy(head->str, cur1->str);
head->count=cur1->count;
head->prev=NULL;
head->next=NULL;
cur2=head;
}
else
{
cur2->next=new word;
cur2->next->str=new char[str_len];
strcpy(cur2->next->str, cur1->str);
cur2->next->count=cur1->count;
cur2->next->prev=cur2;
cur2=cur2->next;
cur2->next=NULL;
}
}
cur1=cur1->next;
}
return head;
}
//вывод содержимого списка в файл
int print_words(const char *filename, word *head)
{
ofstream f;
f.open(filename);
if (f.fail())
{
cout<<"Error! Can't open file "<<filename<<" !"<<endl;
return 0;
}
word *cur=head;
while (cur)
{
f<<cur->str<<" "<<cur->count<<endl;
cur=cur->next;
}
f.close();
return 1;
}
int main()
{
clrscr();
ifstream f;//входной файл
f.open("input.txt");
if (f.fail())
{
cout<<"Error! Can't open file!"<<endl;
return -1;
}
word *all_words=NULL;//все слова
char *temp=new char[str_len];//сюда будем считывать набор символов, отделённых пробелами, табуляциями и переходами на новую строку
while (!f.eof())//пробегаем по всему файлу
{
f>>temp;//считываем набор символов
temp=remove_delims(temp);//получаем слово, т.е. удаляем знаки препинания в конце набора символов
add_word(all_words, temp);//добавляем слово в список
}
word *odd_letters=odd(all_words);//список слов с нечётным количеством букв
word *middle=public_in_middle(odd_letters);//список слов с нечётнымм кол-вом букв и гласной посередине
middle=sort_words(middle);//сортируем список слов с гласной по середине
//вывод в файл
if (print_words("all.txt", all_words)!=1 || print_words("odd.txt", odd_letters)!=1 || print_words("sorted.txt", middle)!=1)
{
cout<<"Error! Can't save data to file!"<<endl;
return -1;
}
//освобождение памяти
delete temp;
return 0;
}