Консультация № 175019
08.12.2009, 08:59
35.00 руб.
0 26 1
Уважаемые эксперты нужно с-тьфайл F, заполненный целыми числами из диапазона [1;100].Вместо первого десятка элементов файла, в тот же файл записать их среднее арифметическое(если среднее арифм. не целое число то округлить), вместо второго десятка - их среднее арифметическое, и.т.д. К-во элементов файла F может не делиться нацело на 10 поэтому последнее среднее арифметическое необходимо вычислить из оставшихся элементов файла
пример. первонач. файл :210352527635891
33
2. Вычислить контрольную сумму полученого файла F, открыв его заново как нетипизированный
нельзя заводить вспомогательные файлы и массивы.*
если можно то с коментариями**спс

Обсуждение

Неизвестный
08.12.2009, 11:18
общий
люди помогите оч срочно надо, напишите плз, я заплачу если че.
Неизвестный
08.12.2009, 11:21
общий
немного не понятно, в каком виде файл:

пример. первонач. файл :210352527635891
33


можно поподробнее о структуре файла?
Неизвестный
08.12.2009, 11:24
общий
ну вводятся с клавиатуры такие числа 210352527635891 и считается среднее арифметич каждого десятка это 33
Неизвестный
08.12.2009, 11:27
общий
т.е 2103525276 среднее ариф =3, для 35891 тоже 3
Неизвестный
08.12.2009, 11:36
общий
Хмм... дак файл должен быть текстовым или байтовым?
Если учесть, что диамазон чисел [1;100], то как отличить, что строка 2103525276 - это числа 2, 1, 0, 3, 5, 2, 5, 2, 7, 6, а не 21, 035, 25, 27, 6 ?
И в-третьих: среднее арифметическое 35891 = 5, а не 3.
Неизвестный
08.12.2009, 11:43
общий
Ну числа 2, 1, 0, 3, 5, 2, 5, 2, 7, 6 вот так вот(написал неподумав) а среднее арифм реально 5, главное смысл ты понял
Неизвестный
08.12.2009, 11:46
общий
а каким должен быт файл в задаче не указано я незнаю
Неизвестный
08.12.2009, 11:49
общий
точно не текстовый
Неизвестный
08.12.2009, 12:18
общий
это ответ
Здравствуйте, Кусмарцев Андрей Валерьевич.
Пришлось повозиться, чтоб не использовать вспомогательные массивы и файлы. Файл я зделал байтовый. Программа в приложении.
Пытался максимально закомментировать код.
Строчки, обозначенные *Для тестирования* можно убрать. Они выводят промежуточные результаты в окно для визуализации работы приложения и удобства тестирования.
Если что не понятно, пиши.

Приложение:
program Proga;

var F:File of byte;
i:integer;
by:byte;
s:integer;
ps:integer;
n, m:integer;
begin
{ Заполняем файл случайными числами от 1 до 100}
Assign(F, 'Fail.dat');
Rewrite(F);
for i:=1 to 74 do
begin
by:=random(100)+1;
Write(F, by);
end;
Close(F);
{ Щитаем среднее арифметическое каждого десятка}
Assign(F, 'Fail.dat');
Reset(F);
s:=0; { Сумма элементов }
n:=0; { Кол-во уже прочитанных чисел за этот раз }
m:=0; { Кол-во записанных арифметических сумм }
while not Eof(F) do
begin
Read(F, by);
Write(by);
Write(' ');
s:=s+by;
inc(n);
if n=10 then { Если уже прочли 10 чисел(байт)}
begin
Writeln(s); { *Для тестирования* }

ps:=FilePos(F); { Запоминаем текущую позицию файла }
Seek(F, m); { Смещаемся в файле на место, куда надо писать }
by:=round(s/n); { Щитаем арифм. сумму }
Writeln(by); { *Для тестирования* }
Write(F, by); { Пишем в файл }
n:=0; { Сбрасываем счетчик }
s:=0; { Сбрасываем сумму}
inc(m); { Смещаем позицию записи }
Seek(F, ps); { Возвращаемся на место, где остановились читать }
end;
end;
if n>0 then { Если осталось что-то в сумме }
begin
Seek(F, m);
Writeln(s); { *Для тестирования* }
by:=round(s/n);
Writeln(by); { *Для тестирования* }
Write(F, by);
inc(m);
end;
Truncate(F); { Обрезаем файл, чтоб остались только суммы }
Close(F); { Закрываем файл }
Readln; { *Для тестирования* }
end.
4
Неизвестный
08.12.2009, 12:24
общий
ах да. Контрольную сумму забыл вычислить... щас исправлю
Неизвестный
08.12.2009, 12:41
общий
Мало пользовался нетипизированными файлами, так-что код, может быть, немного карявый, но щитает правильно.
Добавь в конце программы:
Код:
{ Вычисляем контрольную сумму }
Assign(Fn, 'Fail.dat');
Reset(Fn, 1); { Открываем нетипизированный файл с размером блока 1 }
s:=0; { Обнуляем сумму }
while not Eof(Fn) do { Читаем весь файл }
begin
BlockRead(Fn, by, 1); { Читаем очередной байт }
s:=s+by; { Прибавляем прочитанный байт к общей сумме }
end;
Close(Fn); { Закрываем файл }
Write('Контрольная сумма файла = '); { Выводим на экран контрольную сумму }
Writeln(s);
Readln; { Просто так}


И добавь вверху в разделе var переменную
Код:
Fn:File;     { Нетипизированный файл }
Неизвестный
08.12.2009, 12:43
общий
inc(n) она что делает?
Неизвестный
08.12.2009, 12:50
общий
"inc(n)" - это тоже самое, что и "n:=n+1"
Прибавляет к n единичку.
Неизвестный
08.12.2009, 12:50
общий
не работает в Fn:File; просит of
Неизвестный
08.12.2009, 12:53
общий
кинь полную версию кода
Неизвестный
08.12.2009, 12:53
общий
ого. У мну ничего не просит... Ты так сделал:
Код:
var F:File of byte;
i:integer;
by:byte;
s:integer;
ps:integer;
n, m:integer;
Fn:File; { Нетипизированный файл }
?

У тебя Turbo Pascal 7 ?
Неизвестный
08.12.2009, 12:55
общий
Полная версия кода:
Код:
program Proga;

var F:File of byte;
i:integer;
by:byte;
s:integer;
ps:integer;
n, m:integer;
Fn:File; { Нетипизированный файл }

begin
{ Заполняем файл случайными числами от 1 до 100}
Assign(F, 'Fail.dat');
Rewrite(F);
for i:=1 to 74 do
begin
by:=random(100)+1;
Write(F, by);
end;
Close(F);
{ Щитаем среднее арифметическое каждого десятка}
Assign(F, 'Fail.dat');
Reset(F);
s:=0; { Сумма элементов }
n:=0; { Кол-во уже прочитанных чисел за этот раз }
m:=0; { Кол-во записанных арифметических сумм }
while not Eof(F) do
begin
Read(F, by);

Write(by);
Write(' ');

s:=s+by;
inc(n);
if n=10 then { Если уже прочли 10 чисел(байт)}
begin
Writeln(s); { Для тестирования }

ps:=FilePos(F); { Запоминаем текущую позицию файла }
Seek(F, m); { Смещаемся в файле на место, куда надо писать }
by:=round(s/n); { Щитаем арифм. сумму }
Writeln(by); { Для тестирования }
Write(F, by); { Пишем в файл }
n:=0; { Сбрасываем счетчик }
s:=0;
inc(m);
Seek(F, ps);
end;
end;
if n>0 then { Если осталось что-то в сумме }
begin
Seek(F, m);
Writeln(s); { Для тестирования }
by:=round(s/n);
Writeln(by); { Для тестирования }
Write(F, by);
inc(m);
end;
Truncate(F);
Close(F);
Readln; { Для тестирования }
{ Вычисляем контрольную сумму }
Assign(Fn, 'Fail.dat');
Reset(Fn, 1);
s:=0;
while not Eof(Fn) do
begin
BlockRead(Fn, by, 1);
s:=s+by;
end;
Write('Контрольная сумма файла = ');
Writeln(s);
Close(Fn);
Readln;
end.


Только в нем не все комментарии проставлены...
Неизвестный
08.12.2009, 12:57
общий
у меня АБС, щас попробую на 7.0
Неизвестный
08.12.2009, 13:22
общий
да все работает
Неизвестный
08.12.2009, 13:39
общий
что за переменная by?
Неизвестный
08.12.2009, 13:49
общий
и for i:=1 to 74 do почему до 74?
Неизвестный
08.12.2009, 14:03
общий
Просто так. Можешь любое подставить. У тебя в условии не было указано, сколько чисел в файле создавать.
Неизвестный
08.12.2009, 14:04
общий
by - переменная типа byte для хранения байтов при чтении и записи.
Неизвестный
08.12.2009, 14:15
общий
Можеш в краце написать как она работает?
Неизвестный
08.12.2009, 14:52
общий
Комментариев значит тебе не достаточно?
Ну ладно.
Код:
var F:File of byte;
i:integer;
by:byte;
s:integer;
ps:integer;
n, m:integer;
Fn:File; { Нетипизированный файл }


Здесь объявляются переменные. F - типизированный файл, Fn - нетипизированный файл, i, by, s - вспомогательные переменные. ps - переменная для временного хранения позиции в файле, n - число прочитанных байт последовательности из 10 байт, m - позиция записи результата.

Код:
 { Заполняем файл случайными числами от 1 до 100}
Assign(F, 'Fail.dat');
Rewrite(F);
for i:=1 to 74 do
begin
by:=random(100)+1;
Write(F, by);
end;
Close(F);

Здесь просто создаем типизированный файл и пишем туда 74 случайных чисел от 1 до 100. Закрываем файл.
Код:
 { Щитаем среднее арифметическое каждого десятка}
Assign(F, 'Fail.dat');
Reset(F);

Открываем созданный файл Fail.dat
Код:
 s:=0;  { Сумма элементов }
n:=0; { Кол-во уже прочитанных чисел за этот раз }
m:=0; { Кол-во записанных арифметических сумм }

Сбрасываем счетчики и вспомагательные переменные.
Код:
while not Eof(F) do  <-- Цикл, пока не дойдем до конца файла
begin
Read(F, by); <-- Читаем байт
s:=s+by; Прибавляем его к сумме
inc(n); прибавляем единичку к счетчику, который считает кол-во прочитанных байт очередного десятка
if n=10 then { Если уже прочли 10 чисел(байт)} если набрали 10 чисел
begin
ps:=FilePos(F); { Запоминаем текущую позицию файла }
Seek(F, m); смещаемся туда, куда надо писать арифметическую сумму (т.е. в начало файла)
by:=round(s/n); { Щитаем арифм. сумму }
Write(F, by); { Пишем в файл }
n:=0; { Сбрасываем счетчик } начнём считать опять с нуля
s:=0; сбрасываем сумму, т.к. будем щитать сумму следующего десятка
inc(m); Т.к. записали арифм. сумму в файл, надо посчитать позицию, куда будем писать следующую арифм. сумму.
Seek(F, ps); смещаемся обратно на место чтения
end;
end;

Код:
 if n>0 then { Если осталось что-то в сумме }
begin
Seek(F, m);
by:=round(s/n);
Write(F, by);
inc(m);
end;

Эта часть кода обрабатывает тот случай, когда
К-во элементов файла F может не делиться нацело на 10 поэтому последнее среднее арифметическое необходимо вычислить из оставшихся элементов файла

Код:
Truncate(F);

Обрезаем лишки файла. Т.к. файл у нас был 74 байта, а арифметических сумм в нём только 8. Поэтому обрезаем файл до той позиции, в которой находится каретка файла.
Тут, кстати, небольшая ошибочка Надо перед Truncate(F); подставить строчку Seek(F, m);. Щас эта ошибка не мешает, но если кол-во чисел в файле было бы чётное на 10 число (не 74, а 70 или 50), то файл бы не обрезался.

Ммм... как же ещё понятнее то объяснить. В общем алгоритм такой:
создаем файл. Например такой:
2 <-Тек. позиция каретки
1
0
3
5
2
5
2
7
6
3
5
8
9
1


2 2. Смещаем каретку сюда (позиция в m). Пишем пощитанную сумму, делённую на 10 (т.е. арифметическую сумму). Прибавляем к m единицу, чтобы следующую сумму писать в следующий байт. И возвращаемся на сохранённую ранее позицию ps. Читаем дальше...
1
0
3
5
2
5
2
7
6 1. Тек. позиция каретки. Запоминаем эту позицию (в переменную ps)
3
5
8
9
1


Ну как еще объяснить? Я незнаю...
Неизвестный
08.12.2009, 15:45
общий
Ладно спасибо биг, очень помог=)
Форма ответа