Опубликован: 21.03.2012 | Доступ: свободный | Студентов: 3001 / 238 | Оценка: 4.44 / 4.19 | Длительность: 06:43:00
Специальности: Программист
Лекция 4:
Задачи "Операции со сверхбольшими числами"
const mm=100;
var a,b, sum: array [1..mm] of byte;
i, n, m,max, x, k: integer;
strokaA, strokaB: string;
begin
writeln ('первое слагаемое'); readln (strokaA);
writeln ('второе слагаемое'); readln (strokaB);
n:= length (strokaA);
m:= length (strokaB);
if n>m then max:=n
else max:=m;
for i:=1 to n do
begin
val(copy(strokaA, i, 1),x,k);
a[i+(max-n)]:=x;
end;
for i:=1 to m do
begin
val(copy(strokaB, i, 1),x,k);
b[i+(max-m)]:=x;
end;
{======суммирование===========}
for i:=1 to max do
sum[i]:= a[i]+b[i];
for i:=max downto 2 do
begin
sum[i-1]:=sum[i-1] + sum[i] div 10;
sum[i]:= sum[i] mod 10;
end;
{====вывод результата===========}
for i:=1 to max do
write (sum[i]);
end.Тест:
Задача Найти произведение двух сверхбольших чисел.
Идею решения иллюстрирует схема (рис. 3.3):
- возьмем последний элемент массива В; умножаем его на все элементы массива А. Результат храним в массиве Rez;
- суммируем два массива - Sum и сдвинутые на 1 позицию влево элементы массива Rez; Результат заносим в Sum;
- берем следующий элемент массива В (находящийся левее); повторяем с шага 2;
- выводим на экран содержимое массива Sum.
input "первое слагаемое"; a$
input "второе слагаемое"; b$
n = len(a$)
m = len(b$)
dim a(n), b(m), rez(n), sum(n + m)
rem======разбор на цифры============
for i = 1 to n
a(i) = val(mid$(a$, i, 1))
next
for i = 1 to m
b(i) = val(mid$(b$, i, 1))
next
rem==произведение на j-ую цифру=========
for j = m to 1 step -1
for i = 1 to n
rez(i) = a(i) * b(j)
next
for i = n to 2 step -1
rez(i - 1) = rez(i - 1) + rez(i) \ 10
rez(i) = rez(i) mod 10
next
rem====сумма со сдвигом==========
for i = 1 to n
sum(i + j - 1) = sum(i + j - 1) + rez(i)
next
for i = n to 2 step -1
sum(i - 1) = sum(i - 1) + sum(i) \ 10
sum(i) = sum(i) mod 10
next
next
rem====вывод результата==============
for i = 1 to n + m - 1
print sum(i);
next
const mm=100;
var a,b, rez,sum: array [1..mm] of byte;
i, j, n, m, max, x, k: integer;
strokaA, strokaB: string;
begin
writeln ( 'первый сомножитель'); readln (strokaA);
writeln ( 'второй сомножитель'); readln (strokaB);
n:= length(strokaA);
m:= length(strokaB);
{======разбор на цифры===============}
for i:= 1 to n do
begin
val(copy(strokaA, i, 1),x,k);
a[i]:= x;
end;
for i:= 1 to m do
begin
val(copy(strokaB, i, 1),x,k);
b[i]:= x;
end;
{==произведение на j-ую цифру============}
for j:= m downto 1 do
begin
for i:= 1 to n do
rez[i]:= a[i] * b[j];
for i:= n downto 2 do
begin
rez[i - 1]:= rez[i - 1] + rez[i] div 10;
rez[i]:= rez[i] mod 10;
end;
{====сумма со сдвигом==============}
for i:= 1 to n do
sum[i + j - 1]:= sum[i + j - 1] + rez[i];
for i:= n downto 2 do
begin
sum[i - 1]:= sum[i - 1] + sum[i] div 10;
sum[i]:= sum[i] mod 10;
end;
end;
{====вывод результата=================}
for i:= 1 to n + m - 1 do
write (sum[i]);
end.Тест:
Ключевые термины
- "Сверхбольшое число" - число, величина которого выходит за пределы диапазона допустимых значений выделенной для хранения числа ячейки памяти.
Краткие итоги
Операции со "сверхбольшими" числами выполняются по алгоритму:
- число вводится в строковую переменную.
- строка "разбирается на символы, каждый символ помещается в элемент массива, затем переводится в число.
- дальнейшие действия выполняются "поразрядно": умножение каждого элемента на другое число, организация переноса переполнения в старший разряд перенос.
- аналогично (поразрядно) выполняется операция суммирования двух "сверхбольших" чисел.
Набор для практики
Вопросы.
- Каким образом можно ввести с клавиатуры в переменную число, значение которого превышает 2147483647?
- Каким образом можно удвоить введенное с клавиатуры число, значение которого превышает 2147483647?
Упражнения.
- Вычислить NK, (N и K>10).
- Вычислить N! (N-факториал) - произведение чисел натурального ряда до N включительно.
