Добро пожаловать! Это — архивная версия форумов на «Хакер.Ru». Она работает в режиме read-only.
 

[РЕШЕНО] Длинная арифметика [pascal]

Пользователи, просматривающие топик: none

Зашли как: Guest
Все форумы >> [Компилируемые языки] >> [РЕШЕНО] Длинная арифметика [pascal]
Имя
Сообщение << Старые топики   Новые топики >>
[РЕШЕНО] Длинная арифметика [pascal] - 2010-11-25 22:05:05.583333   
v0lume

Сообщений: 310
Оценки: 0
Присоединился: 2009-10-22 20:48:37.160000
знаю, решается в пару действий на jаvа, но нужен паскаль.

есть входной файл. в нём 2 строчки. каждая строчка содержит 1000чезначное число. нужно считать эти два числа и распихать по двум массивам.
string не пройдёт, не влазит (max 255). integer тоже самое.
почитал про eoln() и eof(). попробовал использовать eoln:
while not eoln(input) do for i:=1000 downto 1 do read(input,a[i]); в input:
12345 54321 на выходе при выводе пустой файл.

подскажите в чём ошибка. может есть другой метод считывания - поделитесь.
Post #: 1
RE: Длинная арифметика [pascal] - 2010-11-26 00:42:50.063333   
kreol

Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
А куда ты, собственно, выводишь то? В приведённом коде - никуда :)
Если там дальше и правда есть вывод в консоль/файл, то проверь в дебаггере значение массива `a` после считывания и до вывода.
Post #: 2
RE: Длинная арифметика [pascal] - 2010-11-26 02:16:57.576666   
_SaZ_

Сообщений: 4329
Оценки: 398
Присоединился: 2008-01-30 02:18:05.553333
Напиши свой тип данных. В чём проблема-то?
Post #: 3
RE: Длинная арифметика [pascal] - 2010-11-26 14:22:51.696666   
v0lume

Сообщений: 310
Оценки: 0
Присоединился: 2009-10-22 20:48:37.160000
saz
так в скалярных не может быть больше 256 элементов.

kreol
массив пустой. выводил последние элементы - пусто. дальше обработка значений и вывод в файл.


есть у кого ещё идеи?
Post #: 4
RE: Длинная арифметика [pascal] - 2010-11-26 15:27:45.866666   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
Не парь себе мозг. Во-первых, храни младшие разряды с младшими индексами (hi-endian). То есть:for i:=1 upto 1 do read(input,a[i]);Так на самом деле будет проще – меньше геморроя с индексами. И почти циклы все будут upto, а не downto.
Во-вторых, если string не умеет больше 255 символов, заведи просто массив char'ов. Если в паскале есть массивы переменного размера – то это самое то, что нужно. Если нет, ну выдели фиксированного размера массив, в тысячу элементов. Правда при этом как-то придётся хранить информацию о длине числа в массиве, но тут есть два варианта: либо тип record с массивом и полем used_elems_count, либо терминатор – первый элемент массива, в котором нету цифры будет содержать какое-нибудь специальное значение, скажем 'a'.
Post #: 5
RE: Длинная арифметика [pascal] - 2010-11-26 16:09:24.460000   
kreol

Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
Тфу, блин, чё-та затупил. У тебя цикл совершенно не такой, как должен быть. Что нужно сделать:

1) считать всё: пока не конец файла, считывать строки;
2) пока пока не конец строки, считывать символы в массив.

а у тебя получается:

1) пока не конец (первой) строки, считывать по 1000 символов в массив.

Если индексы точные, то по идее одна строка должна считаться, но лучше сразу править.
Попробуй (a - двухмерный массив 2x1000, i - номер строки, j - номер столбца):

i = 0; j = 0; while not eof(input) do begin while not eoln(input) do begin read(input, a[i, j]); inc(j); end; inc(i); end;
Post #: 6
RE: Длинная арифметика [pascal] - 2010-11-27 14:44:09.063333   
Davey

Сообщений: 45
Оценки: 0
Присоединился: 2010-03-24 14:51:57.760000
Для того чтобы строки были длинными - директива компилятора {$H+}. Но это так - для расширения кругозора… ^^
Строки использовать, разумеется, не надо.

Полезные функции, типо работы с длинными числами, лучше один раз написать, и хранить где-нибудь в коллекции своих модулей, чтобы когда надо что-то очень быстро написать, всё было под рукой.

Вот тебе минимальный наборчик. Тут отдельно функции считывания, вывода, сложения, вычитания, умножения на обычное число и на длинное и сравнение длинный чисел.
Хранятся в массиве целых чисел, где разбиты по базе 10^3.
Писал больше 2-х лет назад, когда был не особо грамотным, но вроде бы работает ^___^

Type TLong = array[-1..10003] of integer; const base = 1000; baselen = 3; function readLong : Tlong; var s : String; i, j, k : integer; x : TLong; begin readln(S); while length(s) mod baselen &lt;&gt; 0 do s := '0' + s; Fillchar (x, sizeof(x), 0); x[0] := length(s) div baselen; k := 0; for i := x[0] downto 1 do begin For j := 1 to baselen do begin inc(k); x[i] := x[i] * 10 + strtoint(s[k]); end; end; readLong := x; end; function EQ (var x, y :Tlong) : shortint; var i : integer; begin if x[0] &gt; y[0] then begin EQ := 1; exit; end; if x[0] &lt; y[0] then begin EQ := -1; exit; end; For i := x[0] downto 1 do begin if x[i] &gt; y[i] then begin EQ := 1; exit; end; if x[i] &lt; y[i] then begin EQ := -1; exit; end; end; EQ := 0; end; function sum (var a, b : TLong) :Tlong; var i, j, t : integer; C : TLong; begin fillchar(c, sizeof(c), 0); c[0] := max(a[0], b[0]); t := 0; for i := 1 to c[0] do begin r := r + a[i] + b[i]; c[i] := t mod base; t := t div base; end; if t &lt;&gt; 0 then begin inc(c[0]); c[c[0]] := t; end; sum := c; end; procedure writelong(var x : TLong); var i : integer; S : String; begin write(x[x[0]]); For i := x[0] - 1 downto 1 do begin s := inttostr(x[i]); while length(s) &lt; baselen do s:= '0' + s; write(s); end; writeln; end; function sub (var a, b : TLong) : Tlong; var i, t : integer; c : Tlong; begin fillchar(c, sizeof(c), 0); t := 0; For i := 1 to a[0] do begin t := a[i] - b[i]; if t &lt; 0 then begin dec(a[i+1]); t := t + base; end; c[i] := t; end; c[0] := a[0]; while (c[c[0]] = 0) and (c[0] &gt; 1) do dec(c[0]); sub := c; end; function scalmul(var a : Tlong; c : integer) : TLong; var i, t : integer; B : TLong; begin fillchar(b, sizeof(b), 0); b[0] := a[0]; t := 0; for i := 1 to b[0] do begin t := t + a[i] * c; b[i] := t mod base; t := t div base; end; while (t &lt;&gt; 0) do begin inc(b[0]); b[b[0]] := t mod base; t := t div base; end; scalmul := b; end; function mul (var a, b : TLong) : TLong; var c : Tlong; i, j, t : integer; begin fillchar(c, sizeof(c), 0); for i := 1 to a[0] do begin t := 0; For j := 1 to b[0] do begin t := t + c[i + j - 1] + a[i] * b[j]; c[i + j - 1] := t mod base; t := t div base; end; j := b[0] + i; while t &lt;&gt; 0 do begin c[j] := t mod base; t := t div base; inc(j); end; end; c[0] := MaxN; while (c[c[0]] = 0) and (c[0] &gt; 1) do dec(c[0]); mul := c; end;
Post #: 7
RE: Длинная арифметика [pascal] - 2010-11-27 17:55:22.993333   
kreol

Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666
2 Davey:

Директивы компилятору зависят от компилятора, а длинных строк в ранних версиях Паскаля не было. Позже (может уже даже в Delphi) появились и динамические строки, и статические неограниченной размерности.
Post #: 8
RE: Длинная арифметика [pascal] - 2010-11-27 20:41:33.923333   
Davey

Сообщений: 45
Оценки: 0
Присоединился: 2010-03-24 14:51:57.760000
quote:

ORIGINAL: kreol
Директивы компилятору зависят от компилятора, а длинных строк в ранних версиях Паскаля не было.

В борландском и в фрипаскале вроде бы работает. Хотя, соглашусь, в ранних версиях наверное не было.
Просто я сильно молодой и такие компиляторы старше меня ;)

Post #: 9
RE: Длинная арифметика [pascal] - 2010-11-29 23:11:25.730000   
v0lume

Сообщений: 310
Оценки: 0
Присоединился: 2009-10-22 20:48:37.160000
davey
мне что то твои функции совсем не понравились.

нашёл другое решение: a:array[0..1000] of integer; s:char; i:integer; -------------------------------- i:=1; while (s&gt;+'0') and (s&lt;='9') do begin a[i]:=s; inc(i); read(s); end; a[o]:=i-1; --------------------------------
записываем всю строку в массив. i-1 будет длинной массива.
так же считывается вторая строка. если нужно сделать математические операции кроме сравнения - переворачиваем массив. если только сравнить, можно не переворачивать.
Post #: 10
RE: Длинная арифметика [pascal] - 2010-11-30 14:36:12.140000   
Davey

Сообщений: 45
Оценки: 0
Присоединился: 2010-03-24 14:51:57.760000
А чем же тебе мои функции не понравились? У меня то без всяких переворачиваний, строк, и к тому же по базе 3, что оптимизирует и память и быстродействие.

Я абиделся :'(
Post #: 11
RE: Длинная арифметика [pascal] - 2010-11-30 21:19:48.100000   
v0lume

Сообщений: 310
Оценки: 0
Присоединился: 2009-10-22 20:48:37.160000
тем и не понравился, что говно.
в частности строкой
readln(s); при s:string;
не знаю насчёт скорости, но по-моему ты не считаешь строку длиннее 256 символов. в моём же случае нужно считать строку длинной в 1000 символов.
не люблю я всякие примудрости в коде, когда можно написать его же пусть и примитивно, но зато он будет универсален (правую границу можно расширить вплоть до >30000 элементов).
моё мнение было сформированно путём только поверхностного анализа твоего когда. я его не разбирал т.к. он мне не нравится.
Post #: 12
RE: Длинная арифметика [pascal] - 2010-11-30 21:52:51.430000   
rgo

Сообщений: 7170
Оценки: 281
Присоединился: 2004-09-25 05:14:25
quote:

ORIGINAL: v0lume
не люблю я всякие примудрости в коде, когда можно написать его же пусть и примитивно, но зато он будет универсален (правую границу можно расширить вплоть до &gt;30000 элементов).

Вся "премудрость" того кода в том, что он работает в системе счисления 2^32 (или 2^64? longint – это сколько?). Твой работает в системе с основанием 10. Тому коду потребуется выполнить в 9-10 раз меньше операций при сложении, и в 81-100 раз меньше операций при умножении.
Правда у него есть свой недостаток: накладные расходы на переводы из одной системы счисления в другую. Что победит – скорость выполнения операций или скорость перевода из одной системы в другую, – будет зависеть от конкретной задачи. Если считать два числа, сложить и вывести результат – то проще это сделать в десятичной системе. Если же вместо сложения надо будет выполнить вычисления на десяток сложений/умножений, то быстрее считать в системе по основанию 2^32.
Post #: 13
RE: Длинная арифметика [pascal] - 2010-12-01 03:24:28.240000   
kreol

Сообщений: 823
Оценки: 0
Присоединился: 2007-03-08 03:13:06.876666

quote:

ORIGINAL: v0lume

тем и не понравился, что говно.

Тебе указали на директиву компилятору. Тебе показали вариант без директив. Ты не разобрался ни в одном из них и после этого говоришь, что код - говно?
Post #: 14
RE: Длинная арифметика [pascal] - 2010-12-01 09:19:06.793333   
MotoKiller

Сообщений: 1732
Оценки: 56
Присоединился: 2008-03-02 20:08:53.810000
Держи, может пригодится. В задании используется арифметика больших чисел.
http://moron.1side.ru/programmirovanie/borland-turbo-pascal/faktorial-bolshix-chisel.php&nbsp;
Post #: 15
Страниц:  [1]
Все форумы >> [Компилируемые языки] >> [РЕШЕНО] Длинная арифметика [pascal]







Связаться:
Вопросы по сайту / xakep@glc.ru

Предупреждение: использование полученных знаний в противозаконных целях преследуется по закону.