Читал раздел в FAQ и поиск результатов тоже не дал. Помогите с решением задачи!
Дан файл f компонентами которого являются целые числа.Число компонент делится на 4. Никакая из компонент не равна нулю. Файл f содержит равное кол-во отрицательных и положительных компонент.Переписать компоненты этого файла в файл k так, чтобы в файле k числа шли в след. порядке: 2 отрицательных,2 положительных,2 отриц.,2 положит. и т.д.
Подскажите как это реализовать,пожалуйста. Заренее благодарен.
мисс_граффити
25.03.2007 19:33
Можно пойти таким путем: переносим все отрицательные числа в новый файл, между ними вставляя, например, ноль. То есть получаем последовательность типа -1 -2 0 0 -4 -5 0 0 -9 -11 0 0 за второй проход заменяем все нули положительными числами из старого файла. алгоритм упрощается до предела, возвратов назад в файле немного: фактически, все делается за 2 прохода в каждом из файлов.
volvo
25.03.2007 20:07
Можно сделать за один проход... Вот тут было нечто очень похожее, только там надо было чередовать положительные/отрицательные числа: Сурсы -> Типизированные файлы
мисс_граффити
25.03.2007 20:23
там постоянно приходится возвращаться:
seek(f, pos); ... seek(f, neg);
это не один проход (если понимать под проходом считывание каждого элемента по одному разу). а за счет того, что нам надо по два элемента, этот показатель еще ухудшится... если я правильно поняла.
хотя, конечно, новый файл меньше мучаем.
Гость
26.03.2007 3:29
Хочу задать вопрос...вы посчитаете его думаю глупым,но и всё же. А данный файл f мы используем только для чтения и копирования в другой файл компонен?
volvo
26.03.2007 3:33
В принципе, это то, что требовалось по условию:
Цитата(Условие)
... Переписать компоненты этого файла в файл k ...
Гость
26.03.2007 20:14
А что должно быть в самом файле f? Вот как у меня получается:
var f:file of integer; fileName:string; i,n,next:integer; p:array [1..100] of integer; begin Assign(f,'FileName.tip'); rewrite(f); writeln('Vvedite kol-vo komponent(n/4)'); readln(n); writeln('Vvedite komponenti(p<>0)'); for i:=1 to n do begin readln(p[i]); end; close(f); readln; end.
Я правильно понимаю,что данные нужно ввести все с клавиатуры? А то, что кол-во положительных и отрицательных компонент в файле нужно просто записать как комментарий например?Или оно должно уравниваться в самом тексте написания файла? Не совсем даже (как оказалось ) понимаю как создать днный файл...
мисс_граффити
26.03.2007 20:26
ты их заносишь в массив, а надо - в файл. так файл останется пустым.
Гость
26.03.2007 20:44
нужно просто без массива? так?
var f:file of integer; fileName:string; i,n,p,next:integer; begin Assign(f,'FileName.tip'); rewrite(f); writeln('Vvedite kol-vo komponent(n/4)'); readln(n); writeln('Vvedite komponenti(p<>0)'); for i:=1 to n do begin readln(p); write(f,p); end; close(f); readln; end.
Гость
27.03.2007 15:36
Помогите плиз!!! в самом файле (данном якобы) данные вводиться должны с клавиатуры?Или они должны быть заданы константой, чтобы можно бфло работать с этим файлом...??
мисс_граффити
27.03.2007 18:39
можешь написать отдельную программку, ею создавать и заполнять файл. тогда для этой программы файл действительно будет дан.
Гость
27.03.2007 19:20
Осталось для меня проблемой чередование по 2 отрицательных и положительных компонента. Не получается сделать так. Там нужен массив? Если да, то тогда же тип не позволяет создать массив. Просмотрел также и ссылку с похожей задачей...но не смог реализовать именно своё условие...может помогите мне с началом реализовки этого...хочется сделать самому,а никак:(
мисс_граффити
27.03.2007 19:25
зачем массив? ты пробовал(а) реализовать предложенный мной вариант? показывай попытки...
Гость
27.03.2007 19:36
Я его даже не сохранил... так как постоянно показывало,что тип не соответствует... если не нужен массив... сейчас попробую без массива...
Гость
27.03.2007 22:45
что-то совсем не получается ничего.Еще и ошибка теперь:(А завтра уже нужно сдавать:( посмотрите плиз...
Assign(f,'f.dan'); rewrite(f); Assign(g,'g.dan'); rewrite(g); writeln('Vvedite kol-vo komponent(n/4)'); readln(n); writeln('Vvedite komponenti(p<>0):'); for i:=1 to n do begin readln(p); write(f,p); end; close(f); reset(f); for i:=1 to n do begin read(f,p); write(p,' '); close(f); reset(f); for i:=1 to n do begin read(f,p); if p<0 then write(g,p); end; end; while not eof(f) do begin read(f,p); if p>0 then write(g,p); end; close(g); reset(g); for i:=1 to n do begin read(g,p); write(p,' '); end; close(f); close(g); readln; end.
мисс_граффити
28.03.2007 2:28
сделай нормально форматирование - увидишь ошибку. вложенный цикл по той же переменной...
Гость
28.03.2007 3:31
одну ошибку я нашел и исправил... по-прежнему не могу сделать чередование:( Помогите пожалуйста! Сдавать завтра! Не могу понять и всё
КМА
28.03.2007 3:38
А идея остортировать файл не пойдет??? При этом сортировка будет иметь следующий вид. Первые n/2 элементы будут отрицательными числами, а вторые -- положительными.
Тогда вставлять сразу два из первой половины, и два из второй.
Вся суть состоит только в грамотной сортировке (т. е. на необязательно по возрастанию или убыванию, нам достаточно все отрицательные перенести в правую часть массива). Т. е. мы проходим по первой части и ищем положительные элементы, если мы их нашли, то переходим во вторую часть и ищем отрицательный, затем меняем их местами.
Гость
28.03.2007 3:49
Сейчас что-то еще попробую. Может получится отсортировать или еще как-то...
Гость
28.03.2007 4:21
Ничего у меня не получилось с этой программой (видимо него-то не знаю)... Если сможете, то напишите здесь, может до меня всё-таки дойдет. Спасибо.
КМА
28.03.2007 4:22
должно быть что-то типа этого:
n:=fileSize (f); {количество элементов в файле} j:=(n div 2) -1; for i:=1 to n div 2 do begin seek (f, i-1); read (f, buf); if not (buf<0) {если элемент в первой половине массива не отрицательный} then begin {ищем отрицательный элемент во второй половине} buf2:=0; {соответственно на выходе будет buf2 с положительным элементом, и его номер j} while not (buf2<0) do begin seek (f, j); read (f, buf2); inc (j); end; {j будет хранить текущее положение} {надо бы обменять значения} seek (f, i-1); write (f, buf2); seek (f, j); write (f, buf) end end;
Знаю, что делаю плохо, т. к. код не проверил. Но тут просто наметка алгоритма. Далее думаю все будет просто, когда ты отсортируешь файл, добавляешь два с переди и два с зади.
Тут n-1 т. к. отсчет файла ведется с нуля.
мисс_граффити
28.03.2007 4:27
КМА, а теперь представь затраты по времени на сортировку. И ради чего это? Еще и заданный файл перековеркали... А вдруг он для других целей понадобится. В общем, если не затруднит, поясни преимущества своего метода.
КМА
28.03.2007 4:43
По поводу перековеркать, в условие задачи этого не запрещает =) Реально по поводу памяти согласен, будет менее рационально, и вообще во многом уступает твоему алгоритму, честно, просто хотелось показать еще один вариант.
Мой метод имеет место быть, если скажем половина элементов (а иногда и больше) в правой части отрицательна (хотя может быть с точностью наоборот), тогда будет работать чуть побыстрее твоего, хотя это все еще от кода зависит.
мисс_граффити
28.03.2007 4:52
Цитата
По поводу перековеркать, в условие задачи этого не запрещает =)
Да я и не говорила, что что-то неправильно... Однако посчитать это достоинством алгоритма не могу.
КМА
28.03.2007 5:07
Цитата
Однако посчитать это достоинством алгоритма не могу.
Да я вообще-то тоже. Поразмыслив немного, я все же понял, что твой метод намного эффективнее. Просто хотел предложить альтернативу, а получилось как всегда.
Но ничего, ведь главное поиск новых решений, было бы с чем сравнивать, иначе никогда не найти оптимальный вариант.
Гость
28.03.2007 23:06
мисс_граффити, не могла бы ты показать как твой алгоритм должен выглядеть именно на Паскале. Никак я не сделал. Очень прошу!
Гость
29.03.2007 3:26
Прошу прощения, уже всё сделал. предыдущее сообщение оставлял здесь в отчании,но уже всё сделал. Спасибо всем!
КМА
29.03.2007 3:52
Можно модернизировать и тому подобное, вообще наколдовал на скорую руку. Необходимые комменты я сделал.
CONST n=8; VAR inFile, outFile: file of integer; i, j, k: byte; buf: integer; BEGIN assign (inFile, 'C:\inFile.kma'); {------------------- Программу желательно сделать отдельно --------------------} {это ввод в файл, здесь n просто для удобства, в идеале можно задать любое n, или запросить у пользователя} reWrite (inFile); for i:=1 to n do begin write ('Count ->'); readLn (buf); write (inFile, buf) end; close (inFile); {----------------------} {Далее идет сама программа, решающая твою задачу по алгоритму miss graffiti}
{т. к. я знаю количество элементов файла, то я сразу пишу n, реально его можно получить с помощью: n:=FileSize (inFile) } assign (outFile, 'C:\outFile.kma'); reWrite (outFile); reSet (inFile); j:=0; for i:=1 to n do {можно и заменить на while not EoF(inFile) do } begin read (inFile, buf); if buf<0 then begin inc (j); write (outFile, buf); if j=2 then begin j:=0; buf:=0; write (outFile, buf); write (outFile, buf) end end; end; seek (inFile, 0); j:=2;{ устанвливаем запись 2, т. к. нумерация начинается с 0} k:=0; while not EoF (inFile) do begin read (inFile, buf); if buf>=0 then begin seek (outFile, j); write (outFile, buf); inc (j); inc (k); if k=2 then begin k:=0; j:=j+2; end; end; end; close (inFile); close (outFile);
{ вывод второго файла} reSet (outFile); while not eof (outFile) do begin read (outFile, buf); write (buf, ' ') end; readLn; END.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.