Консультация № 178390
14.05.2010, 19:01
0.00 руб.
0 4 1
Доброго времени суток, дорогие эксперты.
Требуется решить задачу на Code::block
Дан файл, компонентами которого являются n-мерные векторы (n-const).
Векторы с наибольшим модулем перенести в конец файла.

Если возможно, то не использовать вспомогательный фаил.

Алгоритм(помогите запрограммировать:
1)открыть фаил для чтения и для записи(не стирая содержимого, так как там векторы будут)
2)Среди всех записей векторов найти те векторы, чьи модули равны и самые большие по отношению к другим модулям других векторов.
3)Перенести эти Векторы с максимальным модулем в конец.
4) закрыть фаил

Фаил должен быть представлен в машинном представлении!
В оригинальной методичке формулировалось так(вдруг я ошибся)
()в исходных файлах информация хранится в машинном представлении.()

Спасибо за внимание.

Обсуждение

давно
Профессор
230118
3054
18.05.2010, 01:08
общий
Юдин Евгений Сергеевич:
Даже если открыть файл для чтения/записи, нельзя будет в нем удалять куски из середины. Предлагаю сделать отображение файла в памяти(mapping), с ним делать что угодно, а потом записать все обратно в файл.
Неизвестный
18.05.2010, 13:34
общий
Вы можете продемонстрировать это в решении?
Неизвестный
18.05.2010, 20:19
общий
Юдин Евгений Сергеевич:
Например, можно решить вот так:
Код:
#include <iostream>
#include <io.h>
#include <math.h>
#include <conio.h>
#include <stdio.h>
using namespace std;

#define n 3 //размерность

void CreateFile () //например, так можно создать файл
{
FILE* fl;
fopen_s (&fl, "c:\\in", "wb");
int a[] = {3, 4, 5};
int b[] = {1, 2, 3};
for (int i=0; i<3; i++) {
fwrite (a, sizeof(int), n, fl);
fwrite (b, sizeof(int), n, fl);
}
fclose (fl);
}

double Module (int* a) //вычисление модуля
{
double s = 0;
for (int i=0; i<n; i++)
s+=(a[i]*a[i]);
return sqrt (s);
}

int main(int argc, char* argv[])
{
//CreateFile (); - можно создать файл
FILE* fl, *tmp;
fopen_s (&fl, "c:\\in", "rb"); //входной
fopen_s (&tmp, "c:\\tmpout", "wb"); //временный

long len = _filelength (_fileno (fl)); //длина файла
int count = len/(n*sizeof(int)); //число векторов в нём

int buf[n]; //буфер для чтения
double max; //максимальный модуль
double *mod = new double [count]; //модули
int ind = 0;

while (!feof(fl)) { //считаем модули векторов и сохраняем
int k = fread (buf, sizeof(int), n, fl);
//если считалось меньше запрошенного - в формате файла ошибка
if (k!=n) {cout << "Error while reading"; _getch(); return -1;}
mod[ind] = Module (buf);
ind++;
if (ind>=count) break;
}
fseek (fl, SEEK_SET, 0); //идём в начало файла

max = mod[0]; //ищем максимальный модуль
for (int i=1; i<ind; i++)
if (mod[i]>max) max=mod[i];

for (int i=0; i<ind; i++) { //переписываем все, кроме максимальных
fread (buf, sizeof(int), n, fl);
if (mod[i]==max) continue;
fwrite (buf, sizeof(int), n, tmp);
}
fseek (fl, SEEK_SET, 0);
for (int i=0; i<ind; i++) { //переписываем максимальные
fread (buf, sizeof(int), n, fl);
if (mod[i]!=max) continue;
fwrite (buf, sizeof(int), n, tmp);
}
fclose (fl); //закрываем файлы
fclose (tmp);

remove ("c:\\in"); //удаляем старый
rename ("c:\\tmpout", "c:\\in"); //переименовываем новый в старый

cout << "Success";

_getch();
return 0;
}

Я работаю в среде Visual Studio, так что не знаю, скомпилируется ли у Вас с ходу. Программа проверена, если устраивает, выложу ответом. Временный файл используется.
Неизвестный
19.05.2010, 02:39
общий
это ответ
Здравствуйте, Юдин Евгений Сергеевич.
Вот вариант с использованием временного файла. Используется самый стандартный для такого случая способ: создаётся новый файл, в который всё переписывается в нужном порядке, затем старый удаляется, а новый переименовывается. Алгоритм не слишком оптимальный: в сумме выходит три прохода по файлу. Для примера брала целочисленный вектор, функция, которой можно создать входной файл, приведена в начале программы. Во всяком случае, на данном примере Вы можете посмотреть, как происходит работа с файлом, и попробовать реализовать какой-то другой вариант.
Проверялось на Visual Studio, но, думаю, и в Вашей среде проблем возникнуть не должно.
Если что, пишите в мини-форум.
Удачи!

Приложение:
#include <iostream>
#include <io.h>
#include <math.h>
#include <conio.h>
#include <stdio.h>
using namespace std;

#define n 3 //размерность

void CreateFile () //например, так можно создать файл
{
FILE* fl;
fopen_s (&fl, "c:\\in", "wb");
int a[] = {3, 4, 5};
int b[] = {1, 2, 3};
for (int i=0; i<3; i++) {
fwrite (a, sizeof(int), n, fl);
fwrite (b, sizeof(int), n, fl);
}
fclose (fl);
}

double Module (int* a) //вычисление модуля
{
double s = 0;
for (int i=0; i<n; i++)
s+=(a[i]*a[i]);
return sqrt (s);
}

int main(int argc, char* argv[])
{
//CreateFile (); - можно создать файл
FILE* fl, *tmp;
fopen_s (&fl, "c:\\in", "rb"); //входной
fopen_s (&tmp, "c:\\tmpout", "wb"); //временный

long len = _filelength (_fileno (fl)); //длина файла
int count = len/(n*sizeof(int)); //число векторов в нём

int buf[n]; //буфер для чтения
double max; //максимальный модуль
double *mod = new double [count]; //модули
int ind = 0;

while (!feof(fl)) { //считаем модули векторов и сохраняем
int k = fread (buf, sizeof(int), n, fl);
//если считалось меньше запрошенного - в формате файла ошибка
if (k!=n) {cout << "Error while reading"; _getch(); return -1;}
mod[ind] = Module (buf);
ind++;
if (ind>=count) break;
}
fseek (fl, SEEK_SET, 0); //идём в начало файла

max = mod[0]; //ищем максимальный модуль
for (int i=1; i<ind; i++)
if (mod[i]>max) max=mod[i];

for (int i=0; i<ind; i++) { //переписываем все, кроме максимальных
fread (buf, sizeof(int), n, fl);
if (mod[i]==max) continue;
fwrite (buf, sizeof(int), n, tmp);
}
fseek (fl, SEEK_SET, 0);
for (int i=0; i<ind; i++) { //переписываем максимальные
fread (buf, sizeof(int), n, fl);
if (mod[i]!=max) continue;
fwrite (buf, sizeof(int), n, tmp);
}
fclose (fl); //закрываем файлы
fclose (tmp);

remove ("c:\\in"); //удаляем старый
rename ("c:\\tmpout", "c:\\in"); //переименовываем новый в старый

cout << "Success";

_getch();
return 0;
}#include <iostream>
#include <io.h>
#include <math.h>
#include <conio.h>
#include <stdio.h>
using namespace std;

#define n 3 //размерность

void CreateFile () //например, так можно создать файл
{
FILE* fl;
fopen_s (&fl, "c:\\in", "wb");
int a[] = {3, 4, 5};
int b[] = {1, 2, 3};
for (int i=0; i<3; i++) {
fwrite (a, sizeof(int), n, fl);
fwrite (b, sizeof(int), n, fl);
}
fclose (fl);
}

double Module (int* a) //вычисление модуля
{
double s = 0;
for (int i=0; i<n; i++)
s+=(a[i]*a[i]);
return sqrt (s);
}

int main(int argc, char* argv[])
{
//CreateFile (); - можно создать файл
FILE* fl, *tmp;
fopen_s (&fl, "c:\\in", "rb"); //входной
fopen_s (&tmp, "c:\\tmpout", "wb"); //временный

long len = _filelength (_fileno (fl)); //длина файла
int count = len/(n*sizeof(int)); //число векторов в нём

int buf[n]; //буфер для чтения
double max; //максимальный модуль
double *mod = new double [count]; //модули
int ind = 0;

while (!feof(fl)) { //считаем модули векторов и сохраняем
int k = fread (buf, sizeof(int), n, fl);
//если считалось меньше запрошенного - в формате файла ошибка
if (k!=n) {cout << "Error while reading"; _getch(); return -1;}
mod[ind] = Module (buf);
ind++;
if (ind>=count) break;
}
fseek (fl, SEEK_SET, 0); //идём в начало файла

max = mod[0]; //ищем максимальный модуль
for (int i=1; i<ind; i++)
if (mod[i]>max) max=mod[i];

for (int i=0; i<ind; i++) { //переписываем все, кроме максимальных
fread (buf, sizeof(int), n, fl);
if (mod[i]==max) continue;
fwrite (buf, sizeof(int), n, tmp);
}
fseek (fl, SEEK_SET, 0);
for (int i=0; i<ind; i++) { //переписываем максимальные
fread (buf, sizeof(int), n, fl);
if (mod[i]!=max) continue;
fwrite (buf, sizeof(int), n, tmp);
}
fclose (fl); //закрываем файлы
fclose (tmp);

remove ("c:\\in"); //удаляем старый
rename ("c:\\tmpout", "c:\\in"); //переименовываем новый в старый

delete [] mod;
cout << "Success";

_getch();
return 0;
}
Форма ответа