Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Файлы.Удаление отрицательного числа

Автор: BSS 22.03.2010 2:56

Помогите пожалуйста решить задачу:
В файле целых чисел, если перед положительным числом стоит отрицательное, то удалить это отрицательное число

Автор: Ozzя 22.03.2010 15:26

Ну, сначала, наверное, прочитать литературу по этой теме, например тут - http://zeus.sai.msu.ru:7000/programming/bp70_lr/lr14.shtml#2
Затем, попробовать написать свой вариант. И, тогда, если будут какие-то непонятки. ;)
Уже и спросить.

Автор: BSS 26.03.2010 5:37

Спасибо за полезную информацию, но хотелось бы видеть грамотное решение, чтобы его потом детально разобрать

Автор: volvo 26.03.2010 6:40

Цитата
хотелось бы видеть грамотное решение, чтобы его потом детально разобрать
Да не надо тебе ничего разобрать, не болтай. Сдать тебе надо решение, вот и весь сказ... Я вон вижу, как ты изо всех решений, которые существуют в сети, выбрал самые бредовые для соседней темы (про Фибоначчи). Разобраться ему надо... Сейчас прям... Чего ж там не разбирался? Уж что-что, а тема чисел Фибоначчи замусолена так, что не найти грамотную рекурсивную реализацию может только слепой.

Автор: BSS 26.03.2010 7:13

Ткните пальцем

Автор: BSS 19.04.2010 3:44

ну как реализовать проверку и удаление?

program p11;
uses crt;
var
f: file of integer;
s:string;
x,n,i:integer;
Begin
writeln('input name of file:');
readln(s);
Assign (f,s);
rewrite(f);
writeln('input amount of numbers:');
readln(n);
for i:=1 to n do
begin
readln(x);
write(f,x);
end;
close(f);
reset(f);
while not eof(f) do
begin
read(f,x);
if x<0
//
//
end;
end.

Автор: Lapp 19.04.2010 6:30

Цитата(BSS @ 19.04.2010 0:44) *
ну как реализовать проверку и удаление?
Заведи два файла: f1 и f2. Один для чтения, а во второй пиши по мере чтения (используй для него временное имя, типа 'file.tmp'). Когда встретится отрицательное перед положительным - пропускай запись. В конце удали входной файл, а временный переименуй в него. Можно это проделать и с одним файлом, но так проще.

Автор: BSS 19.04.2010 12:27

Спасибо, но я не пойму, как мне в файле определить, что отрицательное число стоит перед положительным?

Автор: Ozzя 19.04.2010 13:13

 reset(f);
i:=0;
while not eof(f) do
begin
seek(f,i);
read(f,x);
seek(f,i+1);
read(f,n);

if (x>0) and (n<0) then
writeln(x);
i:=i+1;
end;
close(f);

Проверено на последовательности:
0 -3 1 -2 1 0 -3 1 1 -3
Ответы:
1 1
То есть, найдены 3-й и предпоследний элементы. Возможные косяки ищите сами.

Автор: BSS 19.04.2010 13:39

Цитата(Ozzя @ 19.04.2010 10:13) *

 reset(f);
i:=0;
while not eof(f) do
begin
seek(f,i);
read(f,x);
seek(f,i+1);
read(f,n);
if (x>0) and (n<0) then
writeln(x);
i:=i+1;
end;
close(f);

Проверено на последовательности:
0 -3 1 -2 1 0 -3 1 1 -3
Ответы:
1 1
То есть, найдены 3-й и предпоследний элементы. Возможные косяки ищите сами.

Спасибо

Автор: TarasBer 19.04.2010 14:13

Цитата
Код

while not eof(f) do
   begin
     seek(f,i);
     seek(f,i+1);
     ...
     inc(i)
  end


Ну так-то уж не надо издеваться...

Автор: Ozzя 19.04.2010 14:40

Цитата
Ну так-то уж не надо издеваться...

А в каком месте издевательство?

Автор: TarasBer 19.04.2010 14:53

Файл - это кусок данных с последовательным доступом.
seek, насколько я знаю это ведь отнюдь не переход по массиву, особенно если файл фрагментирован.
Хорошо, если запоминаются текущая и предыдущая позиции и они не вычисляются, но так ли это? Не скрыт ли тут алгоритм маляра?

Автор: Ozzя 19.04.2010 15:48

Исходное задание гласит:

Цитата
В файле целых чисел


Цитата
Файл - это кусок данных с последовательным доступом.
seek, насколько я знаю это ведь отнюдь не переход по массиву, особенно если файл фрагментирован.

Литературу читать не пробовали?
Тут, например:
http://zeus.sai.msu.ru:7000/programming/bp70_lr/lr14.shtml#2

Автор: TarasBer 19.04.2010 16:04

> Литературу читать не пробовали?

Пробовал, не помогает.

> Однако к типизированным и нетипизированным файлам можно
организовать прямой доступ с помощью стандартной процедуры Sееk,
которая перемещает текущую позицию файла к заданному элементу.

И чё? Я этого не знаю?
Так вот, как выглядит этот самый процесс перемещения к заданному элементу для фрагментированного файла? Файл - это не кусок оперативной памяти, к которому сразу можно обратиться по адресу.

Автор: Ozzя 19.04.2010 16:08

Цитата
Так вот, как выглядит этот самый процесс перемещения к заданному элементу для фрагментированного файла?

А я откуда знаю? И Паскаль этого не знает. Точнее, ему это поровну. Вызывает соответствующую функцию ОС.
Цитата
Файл - это не кусок оперативной памяти, к которому сразу можно обратиться по адресу.

К любой компоненте типизированного файла можно обратиться по её номеру.

Автор: volvo 19.04.2010 16:10

TarasBer, не бери на себя функции ОС, договорились? Это ее прерогатива, и она без тебя как-нибудь (получше, чем ты, поверь) разберется, как именно ей организовать переход к следующей записи файла. А то вот таких советов понаслушаются, и начинают писать "оптимизированные" программы. Которые потом, с выходом новой ФС, либо тормозят, либо вообще валятся. Потому что "то что было хорошо для FAT, для NTFS - смерть..." (почти С)

И не надо придумывать и додумывать задание. Там ничего не говорилось о степени фрагментированности файла и его размерах. Иначе я тебе дам вводную, при которой ты можешь даже и не пытаться решить эту задачу. Хочешь? Или поверишь на слово?

Автор: TarasBer 19.04.2010 17:33

> А я откуда знаю? И Паскаль этого не знает.

Тогда почему вы так уверены в том, что это достаточно эффективный метод?

> К любой компоненте типизированного файла можно обратиться по её номеру.

Это к массиву так можно, за несколько тактов. А к файлу? Я, знаешь ли, могу тоже самое сказать про связный список - типа к каждому его элементу можно обратиться по номеру. Ну да, можно, не спорю, но нужно ли?
Файл по структуре к чему ближе - к массиву или к связному списку? Я не знаю.

> TarasBer, не бери на себя функции ОС, договорились?

А я не беру. И даже стараюсь использовать по минимуму. Просто я не понимаю, зачем каждый раз вызывать сложную операцию перехода к другой позиции. Меня не устраивает подход "работает же вроде, чё ещё надо", потому что с таким подходом надо идти на АвтоВАЗ работать.
Я не знаю, как система делает переход к позиции, возможно, что разработчики системы посчитали лишним запоминать предыдущее положение, и каждый вызов Seek будет делать прогон всех фрагментов файла с самого начала, и я не знаю, работает ли Seek за O(1) или за O(n), я не хочу об этом думать. Я лучше отдельно запомню предыдущую переменную, и не буду думать про эти вещи.
И я не знаю, как оно работает, и вы не знаете, но я не такой доверчивый. Я предпочитаю сначала узнать, что это за хрень и что и как она делает, а потом уже применять.

Автор: Lapp 19.04.2010 23:53

Я в принципе согласен с Тарасом. Зачем постоянно позиционировать, если можно просто читать подряд и запоминать предыдущее значение?.. blink.gif

Read(f,i);
while not EoF(f) do begin
Read(f,j);
if (i>=0)or(j<=0) then Write(g,i)
end;
Write(g,j);

Я что-то упускаю?..

Автор: volvo 20.04.2010 1:52

Цитата
Я что-то упускаю?..
Исходный файл:
0, -3, 11, -2, 1, 0, -3, 10, 1, -3, 5


После прогона твоего алгоритма:
Running "f:\programs\test.exe"
0 0 0 0 0 0 0 0 0 0 5

Упускаешь...

Я делал так (запись в файл заменена, для тестирования, на вывод на консоль):
  prev := -1;
save := false; // На всякий случай, если будет пустой файл.
// Не люблю оставлять ВОЗМОЖНОСТЬ для ошибки
while not eof(f) do
begin
save := true;
read(f, next);

if (prev < 0) and (next >= 0) then
else writeln('file -> ', prev);

prev := next;
end;
if save then writeln('file -> ', prev);


TarasBer,
Цитата
И я не знаю, как оно работает, и вы не знаете
А что, Вам известно больше, чем мне о том, что знаю я? Я бы не стал говорить об этом. Я - не студент, который пользуется методичками преподавателей. У меня есть доступ и к более серьезной документации, работа такая...

Цитата
я не хочу об этом думать
нельзя работать ВООБЩЕ нигде, Вам не кажется? Мое мнение о Вас РЕЗКО изменилось после таких заявлений. Больше в дискуссии с Вами я вступать не намерен. Не хотите - не думайте. Bye...

Автор: Lapp 20.04.2010 2:20

Цитата(volvo @ 19.04.2010 22:52) *
Упускаешь...
Упс!.. конечно, упустил.. ((
Read(f,i);
while not EoF(f) do begin
Read(f,j);
if (i>=0)or(j<=0) then Write(g,i);
i:=j // вот это
end;
Write(g,j);


Sorry..

Но я имел в виду другое. Упускаю?.. nea.gif


guys, давайте не выходить за рамки дискуссий по предмету. Личные обиды тут ни при чем, мне кажется.

Автор: mihailov.o.v 22.04.2010 17:58

Цитата(Lapp @ 19.04.2010 22:20) *

Упс!.. конечно, упустил.. ((
Read(f,i);
while not EoF(f) do begin
Read(f,j);
if (i>=0)or(j<=0) then Write(g,i);
i:=j // вот это
end;
Write(g,j);


Sorry..

Но я имел в виду другое. Упускаю?.. nea.gif
guys, давайте не выходить за рамки дискуссий по предмету. Личные обиды тут ни при чем, мне кажется.

Помоему ничего не упускаете, сейчас попробую написать програмку, освежить школьные навыки smile.gif