Модераторы: Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [Pascal] Факториал любого числа, С использованием массива 
:(
    Опции темы
SkipIntro
Дата 2.11.2008, 17:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 2.11.2008

Репутация: нет
Всего: нет



Нужно составить программу для нахождения факториала большого числа (больше 50, допустим).
Для этого надо использовать массив, в котором в ячейке с индексом 0 будет храниться число разрядов текущего результата, в последующих ячейках - сами цифры разрядов.
Допустим, число 7020: A[0]=4, A[1]=0, A[2]=2 и так далее.
При этом умножать надо как бы столбиком.
Не могу никак сделать это самое умножение... Вот то, что надумал за некоторое время, естественно, не работает...
Код

program factorial;

const l=10;

var A:array[0..l] of word;
    n,i,ii,s,n1,n10,n100,n1000,temp:longint;

begin
    WriteLn('‚ўҐ¤ЁвҐ 楫®Ґ зЁб«®');
    ReadLn(n);
    A[0]:=0;
    A[1]:=1;
    for i:=1 to n do
    begin
    n1:=((i mod 1000) mod 100) mod 10;
    if i>=10 then
    n10:=((i mod 1000) mod 100) - n1
    else n10:=0;
    if i>=100 then
    n100:=(i mod 1000) - n10
    else n100:=0;
    if i>=1000 then
    n1000:=n-n100
    else n1000:=0;
     for ii:=1 to l do
      begin
       temp:=A[ii];
       s:=temp*n1 mod 10;
       A[ii]:=A[ii]+s;
      end;
    end;
    for ii:=1 to l do
    Write(A[ii], ' ');
    ReadLn();
end.

Я знаю, что в этом коде много ненужного... В общем, кто-нибудь может предложить что-нибудь по поводу умножения массива столбиком?

PM MAIL   Вверх
darkart
Дата 3.11.2008, 16:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 379
Регистрация: 9.11.2005

Репутация: 26
Всего: 31



Примерно так, оптимизация( если нужна ) за Вамиsmile
Код

program BigFactorial;
const
  MAX_NUMBER_ORDER = 1024;{максимальный порядок числа}
type
  TCipher = 0..9;
  TBigNumber = record
    MaxOrder : integer;{порядок числа}
    OrderNumbers : array [ 0..MAX_NUMBER_ORDER - 1 ] of TCipher;{массив для хранения цифр числа}
  end;
function GetBigNumbersMult( var BigNumberRes, BigNumber1, BigNumber2 : TBigNumber ) : boolean;
{функция возвращает завершилась ли операция умножения успехом,
 произведение 2 чисел BigNumber1 и BigNumber2 сохраняется в BigNumberRes}
var
  i, j, iOrder, iMemoryValue : integer;{i, j - счетчики; iOrder - порядок; iMemoryValue - значение произведения 2 цифр}

begin
  {инициализация результата}
  BigNumberRes.MaxOrder := 0;
  for i := 0 to MAX_NUMBER_ORDER - 1 do
    BigNumberRes.OrderNumbers[ i ] := 0;

  for i := 0 to BigNumber1.MaxOrder do{для всех цифр первого числа}
    for j := 0 to BigNumber2.MaxOrder do{для всех цифр второго числа}
    begin
      iOrder := i + j;{вычисление разряда}
      iMemoryValue := BigNumber1.OrderNumbers[ i ] * BigNumber2.OrderNumbers[ j ];{вычисление длинного значения}

      while( ( iOrder < MAX_NUMBER_ORDER ) and ( iMemoryValue <> 0 ) ) do
      begin
        iMemoryValue := iMemoryValue + BigNumberRes.OrderNumbers[ iOrder ];{добавляем к длинному числу значение уже хранящееся на месте iOrder}
        BigNumberRes.OrderNumbers[ iOrder ] := iMemoryValue mod 10;{оставляем младший разряд}
        iMemoryValue := iMemoryValue div 10;{отбрасываем единицы}
        inc( iOrder );{увеличиваем порядок}
      end;
      if( iMemoryValue <> 0 ) then{вышли из цикла по первому условию и iOrder слишком велик}
      begin
        GetBigNumbersMult := false;{неудача}
        Exit;{выход}
      end;
    end;

  {вычисляем порядок числа}
  i := MAX_NUMBER_ORDER - 1;
  while( ( i > 0 ) and ( BigNumberRes.OrderNumbers[ i ] = 0 ) ) do{ищем первый ненулевой показатель с конца массива}
    dec( i );
  BigNumberRes.MaxOrder := i;{записываем порядок}
  GetBigNumbersMult := true;{умножение завершилось удачно}
end;

procedure CreateBigNumberFromInteger( var BigNumber : TBigNumber; iNumber : integer );
{процедура заполняет запись BigNumber информацией о числе iNumber}
var
  iOrder : integer;{iOrder - порядок}
begin
  iOrder := 0;{инициализация порядка}
  BigNumber.OrderNumbers[ 0 ] := 0;{инициализация 0 порядка числа}
  while( iNumber <> 0 ) do
  begin
    BigNumber.OrderNumbers[ iOrder ] := iNumber mod 10;{вычисление цифры для нужного порядка}
    iNumber := iNumber div 10;{отрезаем единицы}
    inc( iOrder );{увеличиваем порядок}
  end;
  if( iOrder > 0 ) then{iOrder опережает порядок на 1, исключая единицы}
    dec( iOrder );
  BigNumber.MaxOrder := iOrder;{записываем порядок}
end;

function GetFactorial( var BigNumberRes : TBigNumber; iNumber : integer ) : boolean;
{функция пытается вычислить факториал числа iNumber и если вычичление прошло удачно
записывает результат в BigNumberRes и возвращает true, иначе возвращает false}
var
  i, j : integer;{i, j - счетчики}
  BigNumber1, BigNumber2 : TBigNumber;{вспомогательные числа}
begin
  if( iNumber < 0 ) then{факториал определен для целых неотрицательных чисел}
  begin
    GetFactorial := false;{факториал не получен}
    Exit;{выходим из функции}
  end;

  if( iNumber > 2 ) then{ если число больше 2 }
  begin
    CreateBigNumberFromInteger( BigNumber1, iNumber );{запоминаем собственно число в BigNumber1}
    dec( iNumber );{уменьшаем исходное число}
    for i := iNumber downto 2 do{ далее необходимо iNumber - 1 умножение больших чисел для вычисления результата}
    begin
      CreateBigNumberFromInteger( BigNumber2, i );{создаем большое число из следующего множителя}
      if( not GetBigNumbersMult( BigNumberRes, BigNumber1, BigNumber2 ) ) then{если перемножение завершилось неудачей}
      begin
        GetFactorial := false;{факториал не получен}
        Exit;{выходим из функции}
      end
      else{иначе}
      begin
        {Перемещаем результат в BigNumber1}
        for j := 0 to BigNumberRes.MaxOrder do
          BigNumber1.OrderNumbers[ j ] := BigNumberRes.OrderNumbers[ j ];
        BigNumber1.MaxOrder := BigNumberRes.MaxOrder;
      end;
    end;
  end
  else{иначе}
  begin
    if( iNumber = 0 ) then{факториал 0 = 1, иначе равен собственно числу}
      iNumber := 1;
    BigNumberRes.OrderNumbers[ 0 ] := iNumber;
    BigNumberres.MaxOrder := 0;
  end;
  GetFactorial := true;{раз дошли до конца функции, значит все посчитано}
end;

procedure PrintBigNumber( var BigNumber : TBigNumber );
{процедура печати большого числа}
var
  i:integer;{i - счетчик}
begin
  for i := BigNumber.MaxOrder downto 0 do{для каждого разряда печатаем свою цифру}
    write( BigNumber.OrderNumbers[ i ] );
end;

var
  iNumber : integer;{вводимое число}
  BigNumberRes : TBigNumber;{результат вычисления факториала}
  bRes : boolean;{удалось ли вычислить факториал}
begin
  writeln( 'Please enter a number (>=0):' );
  repeat
    readln( iNumber );{ввод числа}
    if( iNumber < 0 ) then
      writeln( 'Invalid number. Number must be >=0. Please reenter number(>=0):' );
  until iNumber >= 0;
  bRes :=  GetFactorial( BigNumberRes, iNumber );{узнаем хватило ли точности для вычисления}
  if( bRes ) then{точности хватило, печатаем результат}
  begin
    writeln( 'Results...' );
    write( 'Factorial = ' );
    PrintBigNumber( BigNumberRes );{печать большого числа}
    writeln;
    writeln( 'Order = ', BigNumberRes.MaxOrder + 1 );{добавляем единицу, так как у нас порядок начинается с 0}
  end
  else{точность мала, нужен больший по размеру массив}
    writeln( 'Error: BIG, REAL BIG NUMBER!!!' );
  readln;{ждем ввода}

end.


PM MAIL WWW ICQ Skype GTalk   Вверх
SkipIntro
Дата 5.11.2008, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 2.11.2008

Репутация: нет
Всего: нет



Круто... Теперь я с чистой совестью могу не сдать данную программу, ибо не был бы способен выдать такой код )
PM MAIL   Вверх
deswars
Дата 14.11.2008, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 45
Регистрация: 23.6.2008

Репутация: нет
Всего: нет



darkart а для чего усложнять? 
Это ж учебная прога - раза в 2-3 меньше будет и проще.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Poseidon, Rodman

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Центр помощи | Следующая тема »


 




[ Время генерации скрипта: 0.1263 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.