Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Касаткин С., Раткевич И., Травова Н. - Лаборато...doc
Скачиваний:
24
Добавлен:
22.11.2019
Размер:
1.01 Mб
Скачать
  1. Программа, сортирующая файл по длине строки методом быстрой сортиров­ки.

Программа запоминает в массиве длины строк, считанных из файла, и их позиции в файле ( использование такого массива позволит не переписывать весь файл в опе­ра­тивную память), затем массив сортируется по возрастанию длины строк. В результате мы получим начальные позиции строк в такой последовательности, какая нам нужна. Используя позиционирование, прочитаем строки в нужном порядке и запишем их в результирующий файл.

#include<iostream>

#include<iomanip>

#include<math.h>

#include<conio.h>

#include<String.h>

#include<ctype.h>

#include <stdlib.h>

#include<fstream>

#include<windows.h>

using namespace std;

// структура, соответствующая одной строке файла:

struct stroka

{

long pos; // позиция, с которой начинается строка в файле

int len; // длина строки

};

// пример оформления шаблонной функции:

template <class Type> void swapq(Type &a, Type &b)

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

{

Type tmp;

tmp=a; a=b; b=tmp;

}

// функция быстрой сортировки:

void qusort( stroka *mas, int left, int right )

{

/*параметры: указатель на массив и индексы, определяющие ту часть массива, в которой в данный момент выполняется сортировка */

register int i,j; // индексы элементов

int x;

i=left; j=right;

x=mas[(left+right) / 2].len; // Берем средний элемент в массиве

do // этот цикл будет сравнивать длины строк

{

while( mas[i].len < x && i < right ) i++;

// Находим элемент, который должен стоять правее X

while( mas[j].len > x && j > left ) j--;

// Находим элемент, который должен стоять левее X

if (i <= j )

{

// и меняем их местами:

swapq<stroka>( mas[i], mas [j] );

i++; j--;

}

} while ( i <= j );

/*В результате получили 2 части массива: в одной все элементы меньше X, в другой – больше */

/* Рекурсивный вызов функции сортировки для двух полученных частей массива: */

if ( left < j ) qusort( mas, left, j);

if ( i < right ) qusort( mas, i, right);

}

int main()

{

if(SetConsoleCP(1251)==0)

{

cerr<<"Fialed to set codepage!"<<endl;

}

if(SetConsoleOutputCP(1251)==0)

{

cerr<<"Failed to set OUTPUT page!"<<endl;

}

// Объявляем файлы:

ifstream inf;

char *name=new char[81]; // имя файла

do // повторение ввода имени файла

{

cout<<"Введите имя файла или нажмите <Esc>";

cout<<" для прекращения работы программы ";

name[0]=_getche(); // считываем первый символ

if (name[0]==27) exit(0);

// Если нажата клавиша <Esc>, прерываем выполнение программы

cin.getline(&name[1],80);

// считываем остальные символы имени

inf.open(name); // открываем файл

if (!inf)

cout<<"Файл не найден ! \n";

} while(!inf); /* повторяем ввод, пока имя файла не будет введено правильно */

/* этот цикл стоит рассматривать не как руководство к действию, а скорее как пример возможных вариантов манипуляций со строками */

fstream outf("rez.txt",ios::out);

// файл для записи отсортированного текста

char *str=new char[102]; // строка для чтения файла

char *beg=str; // указатель на начало строки

// Определяем количество строк в файле:

int kol=0;

while ( !inf.eof() )

{

inf.getline(str,102);

kol++;

}

// Создаем массив записей о строках:

stroka *mas = new stroka[kol];

inf.clear();

inf.seekg(0l,ios::beg);

mas[0].pos=0; // позиция первой строки

int l; // длина очередной считываемой строки

// считываем текст построчно:

for (int i = 0; i < kol; i++)

{

str = beg;

/* мы будем изменять значение str, но для каждой новой строки указатель str опять будет хранить адрес начала области памяти, выделенной для строки */

inf.getline(str,102); // считываем строку

l=strlen(str);

if (i < kol-1) // если мы считываем не последнюю строку

{

mas[i+1].pos=inf.tellg();

// запоминаем текущую позицию как начало следующей строки

while ( *str == ' ' || *str == 9 )

{

str++;

mas[i].pos++;

} // обрезали пробелы и знаки табуляции в начале строки

}

mas[i].len = strlen(str) ;

// запомнили длину получившейся строки

}

// Сортируем массив по длине строк:

qusort(mas,0,kol-1);

// считываем текст, используя позиции, хранящиеся в массиве:

inf.clear();

for (int i = 0; i < kol; i++)

{

if (inf.eof()) inf.clear();

// если считана последняя строка в файле

inf.seekg( mas[i].pos, ios::beg );

inf.getline(str,102); // считываем нужную строку

if (*str) outf<<str<<endl;

// и записываем ее в результирующий файл

}

outf.close();

cout<<"Смотрите результат работы программы в файле \"rez.txt\"";

_getch();

return 0;

}