Программа считывает матрицу из файла, выводит ee на экран, сортирует элементы в каждом столбце и отсортированную матрицу записывает в файл.

Этот пример иллюстрирует использование матрицы, размеры которой опре­де­ля­ют­ся в процессе выполнения программы. Размеры матрицы считываются из файла, хотя это необязательно. Размеры матрицы можно определить, подсчитав количество чисел в первой строке и количество строк (если каждая строка матрицы записана как одна строка файла).

#include<iostream>

#include<iomanip>

#include<math.h>

#include<conio.h>

#include<String.h>

#include<ctype.h>

#include <stdlib.h>

#include<windows.h>

#include <fstream> // Этот файл обеспечивает работу с файлами

using namespace std; // !!! Используем стандартное пространство имён

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

void swap(float& a, float& b)

{

float tmp;

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

}

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("test.txt");

ofstream outf("sort.txt");

int m,n; // Количество строк и столбцов

register int i,j;

// счетчики (пример использования регистровых переменных)

inf >> m >> n;

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

float *vek, **mat;

/* Указатель на матрицу как на линейный массив и указатель на массив ука­за­телей для обращения к элементам массива как к элементам матрицы. Элементы мас­сива объявлены как числа, которые могут иметь дробную часть */

vek=new float[m*n]; // выделяем место под элементы матрицы

mat=new float*[m];

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

for (i=0; i<m; i++) // заполняем массив указателями

mat[i]= &vek[i*n]; // деление на строки матрицы

printf("Исходная матрица:\r\n");

// чтение элементов из файла

for (i=0; i<m; i++)

{

for(j=0; j<n; j++)

{

inf>>mat[i][j];

// считываем элемент как слово и записываем в матрицу

if (inf.eof())

// если достигнут конец файла, а матрица еще не заполнена

{

printf("Не хватает данных\r\n");

_getch();

exit(0);

}

printf("%10.2f",mat[i][j]); // вывод элемента на экран

}

printf("\r\n"); // перевод курсора в начало следующей строки

}

// Сортировка по столбцам методом пузырька:

for (j=0; j<n; j++) // проходим по столбцам

for (int p=1; p<m; p++) // отсчитываем проходы по столбцу

for (i=0; i<m-p; i++)

// сравниваем соседние элементы в столбце

if (mat[i][j]>mat[i+1][j])

swap (mat[i][j],mat[i+1][j]);

// и, если нужно, переставляем их

// Запись в файл и вывод на экран полученной матрицы:

cout << "Отсортированная по столбцам: \n";

for (i=0; i<m; i++)

{

for(j=0; j<n; j++)

{

// запись элемента в файл:

outf <<setiosflags(ios::showpoint)<< setprecision(2)<<setw(10)<<mat[i][j];

// вывод на экран:

cout <<setiosflags(ios::showpoint) << setprecision(2)<< setw(10)<<mat[i][j];

// каждый элемент записывается с двумя цифрами после точки в поле из 8 позиций

}

outf<<endl;

// в конце строки матрицы выводим признак конца строки

cout << endl;

}

outf.close();

delete []mat;

delete []vek;

_getch();

return 0;

}

6. Программа, сортирующая файл по длине строки методом быстрой сортиров­ки.

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

#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;

}

Наши рекомендации