Консультация № 178455
18.05.2010, 09:27
35.95 руб.
0 3 1
Доброго времени суток, уважаемые эксперты!
Требуется написать программу на языке Си++ (консоль) Среда - предпочтительно Borland C++Builder 6. Код программы прошу снабдить подробными комментариями. По возможности прошу приложить исполняемый файл.
Задание:

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

Заранее спасибо!

Обсуждение

Неизвестный
18.05.2010, 22:26
общий
это ответ
Здравствуйте, Botsman.
Мой вариант программы приведен в приложении. Программа выводит меню с перечнем возможных операций.

Некоторые замечания:
Класс матрицы (Matrix) реализует операции, специфические для данной задачи. Существует мнение, что правильный подход при реализации классов, использующих динамическое распределение памяти, включает реализацию конструктора копирования и оператора присваивания. Однако, для данной задачи они не нужны, поэтому я их не реализовывал.
Массив элементов матрицы я удаляю посредством delete m_x. Строго по правилам, следует использовать delete[] m_x. Для простых типов компилятор нормально воспринимает delete, а вот для массивов объектов — обязательно использовать delete[].

Программа проверена в MSVC++ 6.0 и Visual Studio 2005. Извините, у меня нет Borland C++Builder 6.

Исполняемый файл
Успехов!

Приложение:
/*
Разработать программу, проверяющую упорядоченность строк заданной
матрицы по убыванию сумм их элементов. Предусмотреть 2 режима -
ручной ввод матрицы и автоматическое заполнение случайными числами.
*/

#include <conio.h>
#include <time.h>

#include <fstream>
#include <iostream>

using namespace std;


class Matrix
{
public:
Matrix( int nRows, int nCols );
~Matrix();

int* operator[]( int iRow );
const int* operator[]( int iRow ) const;
void manual_input();
bool check_order();
void random();

// +ператор ввода
friend istream& operator>>( istream& stream, Matrix& m );
// +ператор вvвода
friend ostream& operator<<( ostream& stream, const Matrix& m );

protected:
int m_nRows, m_nCols;
int* m_x;
};

// возвращает указатель на первый элемент строки iRow (нумерация с 0)
inline int* Matrix::operator[]( int iRow )
{
return m_x + iRow*m_nCols;
}

inline const int* Matrix::operator[]( int iRow ) const
{
return m_x + iRow*m_nCols;
}


Matrix::Matrix( int nRows, int nCols ) :
m_nRows( nRows ), m_nCols( nCols )
{
m_x = new int[ nRows*nCols ];
}

Matrix::~Matrix()
{
delete m_x; m_x = 0;
m_nRows = m_nCols = 0;
}

// чтение матрицы со стандартного ввода или из текстового файла
istream& operator>>( istream& stream, Matrix& m )
{
for( int i=0; i < m.m_nRows; i++ )
for( int j=0; j < m.m_nCols; j++ )
stream >> m[i][j];

return stream;
}

// печать матрицы в текстовый файл или на стандартный вывод
ostream& operator<<( ostream& stream, const Matrix& m )
{
for( int i=0; i < m.m_nRows; i++ ) {
for( int j=0; j < m.m_nCols; j++ ) {
stream.width(5);
stream << m[i][j] << ' ';
}
stream << endl;
}
return stream;
}

// ручной ввод матрицы
void Matrix::manual_input()
{
cout << "Введите элементы матрицы:\n";
for( int i = 0; i < m_nRows; ++i ) {
int* pRow = (*this)[i]; // указатель на начало i-той строки
for( int j = 0; j < m_nCols; ++j ) {
cout << "m[" << i << "][" << j << "] = ";
cin >> pRow[j];
}
}
}

// заполнение матрицы случайными числами
void Matrix::random()
{
srand( time(NULL) ); // инициализируем генератор псевдослучайных чисел
for( int i = 0; i < m_nRows; ++i ) {
int* pRow = (*this)[i]; // указатель на начало i-той строки
for( int j = 0; j < m_nCols; ++j )
pRow[j] = rand() % 1000;
}
}

// Проверяет упорядоченность строк матрицы по убыванию сумм их элементов
bool Matrix::check_order()
{
long prevSum = LONG_MAX; // сумма элементов предыдущей строки
// Сумма элементов первой строки может бvть любой, поэтому
// предыдущую сумму устанавливаем заведомо большой.
// (Здесь предполагается, что сумма элементов строки не достигает LONG_MAX.)

for( int i = 0; i < m_nRows; ++i ) {
long sum = 0;
int* pRow = (*this)[i]; // указатель на начало i-той строки
for( int j = 0; j < m_nCols; ++j ) // вычисляем сумму элементов i-той строки
sum += pRow[j];

if( sum >= prevSum ) // сравниваем с предыдущей строкой
return false; // нарушение упорядочения

prevSum = sum;
}
return true;
}

// функция-обертка: ручной ввод матрицы
void manual_input( Matrix*& pMatrix )
{
int nRows, nCols;
cout << "Введите число строк: ";
cin >> nRows;
if( nRows <= 0 ) {
cout << "Неверное число строк. Отмена операции.\n";
return;
}
cout << "Введите число столбцов: ";
cin >> nCols;
if( nCols <= 0 ) {
cout << "Неверное число столбцов. Отмена операции.\n";
return;
}

if( pMatrix ) {
delete pMatrix;
pMatrix = 0;
}

pMatrix = new Matrix( nRows, nCols );
if( !pMatrix ) {
cout << "Не хватает памяти.\n";
return;
}
pMatrix->manual_input();
}

/* функция-обертка: ввод матрицы из файла

В файле элементы матрицы разделены пробелами и им предшествует
кол-во строк и столбцов
Пример:

5 6
1 3 4 10 11 30
2 5 9 12 19 29
6 8 13 18 20 28
7 14 17 21 24 27
15 16 22 23 25 26

*/
void file_input( Matrix*& pMatrix )
{
cout << "Введите имя файла: ";
char szFileName[_MAX_PATH];
cin >> szFileName;
if( !szFileName[0] ) return; // пустая строка, отмена операции

ifstream fin( szFileName, ios::in );
if( fin.is_open() ) {
if( pMatrix ) {
delete pMatrix;
pMatrix = 0;
}
int nRows, nCols;
fin >> nRows >> nCols;

pMatrix = new Matrix( nRows, nCols );
if( !pMatrix ) {
cout << "Не хватает памяти.\n";
return;
}
fin >> (*pMatrix);
}
else
cout << "Ошибка при открытии файла " << szFileName << endl;
}

// функция-обертка: генерация псевдослучайной матрицы
void random_matrix( Matrix*& pMatrix )
{
if( pMatrix ) {
delete pMatrix;
pMatrix = 0;
}
srand( time(NULL) ); // инициализируем генератор псевдослучайных чисел

// случайное число строк и столбцов
int nRows = 4 + (rand() % 6);
int nCols = 4 + (rand() % 6);
pMatrix = new Matrix( nRows, nCols );
if( !pMatrix ) {
cout << "Не хватает памяти.\n";
return;
}
pMatrix->random();
cout << "Сгенерирована матрица " << nRows << 'x' << nCols << endl;
}

// функция-обертка: проверка упорядоченности строк матрицы
void check_order( Matrix* pMatrix )
{
if( pMatrix ) {
if( pMatrix->check_order() )
cout << "Строки матрицы упорядочены по убыванию сумм их элементов.\n";
else
cout << "Строки матрицы не упорядочены по убыванию сумм их элементов.\n";
}
else
cout << "Матрица не задана\n";
}

// функция-обертка: вывод матрицы на экран
void print_matrix( Matrix* pMatrix )
{
if( pMatrix )
cout << (*pMatrix);
else
cout << "Матрица не задана\n";
}

int main()
{
Matrix* pMatrix = 0;
int ch;
do {
cout << "\n--------------------------\n"
"1- ручной ввод матрицы\n"
"2- чтение матрицы из файла\n"
"3- псевдослучайная матрица\n"
"4- проверка упорядочения\n"
"5- показать матрицу\n"
"--------------------------\n"
"0- выход\n"
"--------------------------\n\n";

// этот цикл позволяет исключить повторный вывод меню при
// нажатии неверной клавиши
do ch = getch(); while( ch < '0' || ch > '5');
switch( ch ) {
case '1': manual_input( pMatrix ); break;
case '2': file_input( pMatrix ); break;
case '3': random_matrix( pMatrix ); break;
case '4': check_order( pMatrix ); break;
case '5': print_matrix( pMatrix ); break;
}
} while( ch != '0' );
return 0;
}
5
Огромное спасибо! Как всегда, вовремя, красиво и правильно!
Неизвестный
19.05.2010, 13:31
общий
Как обычно, я забыл очистить память при выходе. В функции main() между строками
Код:
} while( ch != '0' );
return 0;
надо вставить еще кусочек:
Код:
} while( ch != '0' );
if( pMatrix ) delete pMatrix;
return 0;

Несмотря на то, что для этой программы это несущественно (память все равно освобождается при выходе), ресурсы лучше всегда освобождать явно (если только это не делает деструктор класса при выходе из области видимости).
Приношу свои извинения.
Неизвестный
19.05.2010, 13:45
общий
amnick:
Вряд ли бы я заметил эту ошибку самСпасибо!
Форма ответа