Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Паскаль
Пикап Форум - Всемирный форум пикаперов > Общение > Курилка
DriftKing
Люди, я туплю страшно. Помогите :?
Вообщем задача: Умножить два длинных числа (длинная арифметика).
Дано: Два файла: : 1я строка- длинна 1го числа;2я строка- длинная 2го числа; 3я строка- 1е число; 4я строка- 2е число.
: в нем результат умножения.
Числа заносятся в массивы. перемножаются, и со сдвигом записываются в двумерный массив. Числа с двумерного массива сумируются, и результат заносится в обычный массив. (Вообщем как в столбик, через массивы).

Воть, если что несовсем понятно - спрашивайте. А процедурка нужна поскорее. Ибо последнюю лабу могу завалить :?: :idea:
ЗЫ в инэте смотрел, то что нужно не нашел.
Седрик
(DriftKing)
Люди, я туплю страшно. Помогите :?
Вообщем задача: Умножить два длинных числа (длинная арифметика).
Дано: Два файла: : 1я строка- длинна 1го числа;2я строка- длинная 2го числа; 3я строка- 1е число; 4я строка- 2е число.
: в нем результат умножения.
Числа заносятся в массивы. перемножаются, и со сдвигом записываются в двумерный массив. Числа с двумерного массива сумируются, и результат заносится в обычный массив. (Вообщем как в столбик, через массивы).

Воть, если что несовсем понятно - спрашивайте. А процедурка нужна поскорее. Ибо последнюю лабу могу завалить :?: :idea:
ЗЫ в инэте смотрел, то что нужно не нашел.

Иди Кнута читай ... прохрамисст ))
DriftKing
Я бы с радостью, так у меня времени до пятницы sad.gif

Упрощу задачу, я кое-что уже сделал. Нужно это:
- Есть двумерный массив. Нужно найти сумму его елементов, так, как бы мы сумировали их в столбик.
Допустим вот:
00123
05430
70800
00040
-------
76393

:?
DriftKing
Код написал, проимитировал на бумаге, работает. А в программе считает неверно sad.gif
Eternalko
Не знаю на каком это языкеsmile.gif
Экспромтsmile.gif







//0.КОД И КАММЕНТЫ ЧИТАТЬ ПО ЦИФРАМ!!!! По номерам.



a=new Array; //1. Создаем наш 2Д массив. По трад. будет. а

getIntToArray(a);//2. Заносим туда нашу матрицу. Твоя табличка сложения



funnction sum(array a) //3. Функция, которая как-бы производит сумму этого столбика:)

{

res=new Array; //4.Это наш результат. Будущий) ВАЖНО! Пишу задом наперед!!!! См. каммент №16

int tmp; //5.Для помощи. Тут храниться сумма одного столбика

int k=0,l=0; //6. Доп. переменные. К. счетчик.



for(i=a.getLenght;i>0;i--) //7. "Ставим" "себя" в прав. угол. a.getLenght это ДЛИННА массива. Просто число!

{

while(tmp) //11.Пока тмп больше "0". Будем записывать число за числом из результата нашего столбца в массив. Десяток за десятком

{

l=k; //12. Тут l будет нашим счетчиком чтоб не k "портить".

res[l]=+tmp % 10;  //13. Записывам(добавляем) еще один десяток

l++; //14. увеличиваем, чтоб след. десяток. добавить....

tmp=tmp/10; //15. уменьшаем tmp на 10. На посл. цифру котор. занесли в результат.

}

k++; //16. увелич. счетчик эл-та рез-та.

     for(j=a.getHeight;j>0;j--) //8. Теперь в нижн. прав. угол.

           {

                 tmp+=a[j][i]; //9. Снизу(!) вверх суммируем ВСЕ числа. Сумма столбика:)

           }

}

return reverse(res);//17. Возвращаем наш результат. Вот он супер массив число. Только надо обернуть его, чтоб правильно записалось:)

}



sum(a);^_0
Bordosten
Дрифт отключай пенис и включай мозг laugh.gif
FalseNegative
А в чём трабл-то? Суммирование само по себе просто как мычание... (хотя, давно не писал на паскакале этом, может напутал чегой...)


program arraysum;

var tosum: array [1...100,1..100] of Integer; //Как вариант, - array [] of 0..9;

      actualwidth,actualheight: Integer;

      aresult: array [1..100] of Integer;

begin

//читаем исходный массив.

for i := 1 to actualwidth do

begin

     aresult := 0; //ВАЖНО! В Паскале нет автоинициализации!

     for j := 1 to actualheight do

     begin

       aresult[i]:=aresult[i]+tosum[i,j];

     end;

  end;

  //выводим результатъ

end.
FalseNegative
или вам ещё перенос нужен? т.е.
19
19
--
38
а не
19
19
--
2(18)?

тады так:



program arraysum;

var tosum: array [1...100,1..100] of Integer; //Как вариант, - array [] of 0..9;

      actualwidth,actualheight,resultwidth,cnt,carry: Integer;

      aresult: array [1..100] of Integer;

      go_on:boolean;

begin

//читаем исходный массив.

for i := 1 to actualwidth do

begin

     aresult := 0; //ВАЖНО! В Паскале нет автоинициализации!

     for j := 1 to actualheight do

     begin

       aresult[i]:=aresult[i]+tosum[i,j];

     end;

  end;

  go_on:=true;// или наоборот?

  cnt:=1;

  carry:=0;

  while go_on do

  begin

      aresult[cnt]:=aresult[cnt]+carry;

      carry:=aresult[cnt] div 10;

      aresult[cnt]:=aresult[cnt] mod 10;

      cnt:=cnt+1;

      go_on:=NOT (carry=0 AND aresult[cnt]=0);//Тьху, надо  NOT исправил.

  end;

  resultwidth:=cnt-1;//

  //выводим результатъ

end.
DriftKing
Всем большое пасибо smile.gif Особенно тебе, Негетив. Мне с переносом нужно было))
Етерналко, спс тоже) Это код на С++. Я его знаю, но учить в универе бум тока в след году.
DriftKing
(FalseNegative)
или вам ещё перенос нужен? т.е.
19
19
--
38
а не
19
19
--
2(18)?

тады так:


program arraysum;
var tosum: array [1...100,1..100] of Integer; //Как вариант, - array [] of 0..9;
actualwidth,actualheight,resultwidth,cnt,carry: Integer;
aresult: array [1..100] of Integer;
go_on:boolean;
begin
//читаем исходный массив.
for i := actualwidth downto 1 do
begin
aresult[i] := 0; //ВАЖНО! В Паскале нет автоинициализации!
for j := 1 to actualheight do
begin
aresult[i]:=aresult[i]+tosum[i,j];
end;
end;
go_on:=true;// или наоборот?
cnt:=actualwidth; //actualwidth и actualheight одинаковые, поэтому безразници
carry:=0;
while go_on do
begin
aresult[cnt]:=aresult[cnt]+carry;
carry:=aresult[cnt] div 10;
aresult[cnt]:=aresult[cnt] mod 10;
cnt:=cnt-1;
go_on:=NOT ((carry=0) AND (aresult[cnt]=0));//Тьху, надо NOT исправил.
end;
resultwidth:=cnt-1;// это не нужно
//выводим результатъ
end.

Все отлично, только немного подправить нужно было. Красным дописал что нужно и убрал что нет)[/color][color=#444444]
FalseNegative
Esli u tebja mladshie razrjady v starshih elementah, to s etim kodom vozmozhen access violation na popytke chtenija result[0].
neponjatno kuda devatj dp. razrjady.
i da, tam slozhenie vmesto umnozhenija.
Sorry, pishu s telefona.
Eternalko
А может так оптимальней будет....


program arraysum;

var tosum: array [1...,1...] of Integer; //Почему он должен быть определен?? Вдруг числа оч. большие:)))

actualwidth,actualheight,colsum,k,l: Integer;

aresult: array [1..100] of Integer;

begin



for i := actualwidth downto 1 do

begin





   while colsum do

   begin

    l:=k;

    aresult[l]:=aresult[l]+colsum mod 10;

    colsum:=colsum div 10

    l:=l+1;

   end;



  k:=k+1;



   for j:= actualheight downto 1 do  

   begin

    colsum:=colsum+tosum[j,i];

   end;

end;



end;
[/code]
Eternalko
А... И еще все переменные должны быть по нулямsmile.gif В начале программы)
DriftKing
Етерналко, может и оптимальнее, в паскаль не вставлял, ибо ты юзаешь сдесь динамический массив, а они появляются только в делфи, т.е. в паскале тебе выдаст ошибку smile.gif
Нужно указывать от 1 .. и до какого-то определенного числа. (кстати я пробывал считать в программе число в переменную, потом вызвать процедуру, и сделать массив 1..та переменная. Всеравно не вышло, хотя переменную я считал раньше нежели определил массив, и значение так же передал в процедуру, т.е. в делфи/Си все было бы Окей.

Негетив, Я написал процедуру умножения. Только трабл такой получается. Считает оно все правильно, но только если массивы до 10. Т.е. мое "длинное" число максимум из 10 цыфр. Если больше 10 и где-то до 250 - просто виснет (долго очень думает, я так и не дождался результат. Если же больше 250 - даже не компилируется, сразу кидает ошибку, что мало памяти. А все (на сколько я понимаю) из-за двумерного массива.

Вот мои две процедуры:
Это рандом, который по заданому n генерирует число из n цыфр:


Procedure rndm(n1, n2: integer);

var i,temp: integer;

    f: text;

begin

     randomize;

     assign(f, 'c:\in.txt');

     rewrite(f);

     writeln(f, n1);

     writeln(f, n2);

     temp:= 0;

     while temp = 0 do

           temp:= random(9);

     write(f, temp,' ');

     for i:= 2 to n1 do

          write(f, random(9),' ');

     writeln(f);

     temp:= 0;

     while temp = 0 do

           temp:= random(9);

     write(f, temp,' ');

     for i:= 2 to n2 do

         write(f, random(9),' ');

     close(f);

end;

И вторая, это уже само умножение:


Procedure umnoj;

var f,g: text;

    i,j,k,l,x,y,p,s: integer;

    a,a1,b,b1: array [1..max] of byte;

    c: array [1..max,1..max] of byte;

    go_on: boolean;

begin

     assign(f, 'c:\in.txt');

     assign(g, 'c:\out.txt');

     reset(f);

     rewrite(g);

     for k:= 1 to max do

     begin

          a[k]:= 0;

          a1[k]:= 0;

          b[k]:= 0;

          b1[k]:= 0;

     end;

     for k:= 1 to max do

         for l:= 1 to max do

             c[k,l]:= 0;

     readln(f, i);

     readln(f, j);

     for k:= 1 to i do

         read(f, a1[k]);

     for k:= 1 to j do

         read(f, b1[k]);

     for k:= 1 to max do

     begin

         a[max-i+k]:= a1[k];

         a1[k]:= 0;

     end;

     for k:= 1 to max do

     begin

         b[max-j+k]:= b1[k];

         b1[k]:= 0;

     end;

     p:= 0;

     s:= 0;

     for l:= max downto 1 do

     begin

          for k:= max downto 1 do

              begin

                   p:= a[k]*b[l]+p;

                   c[k-s,max-l+1]:= p mod 10;

                   p:= p div 10;

              end;

          inc(s);

     end;

     for l:= max downto 1 do

     begin

          a1[l]:= 0;

          for k:= 1 to max do

              a1[l]:= a1[l]+c[l,k];

     end;

     go_on:= true;

     l:= max;

     p:= 0;

     while go_on do

     begin

          a1[l]:= a1[l]+p;

          p:= a1[l] div 10;

          a1[l]:= a1[l] mod 10;

          dec(l);

          go_on:= not ((p=0) and (a1[l]=0));

     end;

     for l:= 1 to max do

         write(g, a1[l]);

     close(f);

     close(g);

end;


главная программа:


var n1,n2: integer;

begin

     write('Vvedite dlinnu 1 chisla: ');

     readln(n1);

     write('Vvedite dlinnu 2 chisla: ');

     readln(n2);

     rndm(n1, n2);

     umnoj;

end;


Не пойму что может быть не так :?
DriftKing
Еще забыл,
const max=10; // это максимальная длинна всех массивов.
при 10 все окей, при выше (на >20 точно не работает) нет.
Eternalko
Ну так не надо динамического сделай статический
Седрик
(eternalko)
Не знаю на каком это языкеsmile.gif
Экспромтsmile.gif







//0.КОД И КАММЕНТЫ ЧИТАТЬ ПО ЦИФРАМ!!!! По номерам.



a=new Array; //1. Создаем наш 2Д массив. По трад. будет. а

getIntToArray(a);//2. Заносим туда нашу матрицу. Твоя табличка сложения



funnction sum(array a) //3. Функция, которая как-бы производит сумму этого столбика:)

{

res=new Array; //4.Это наш результат. Будущий) ВАЖНО! Пишу задом наперед!!!! См. каммент №16

int tmp; //5.Для помощи. Тут храниться сумма одного столбика

int k=0,l=0; //6. Доп. переменные. К. счетчик.



for(i=a.getLenght;i>0;i--) //7. "Ставим" "себя" в прав. угол. a.getLenght это ДЛИННА массива. Просто число!

{

while(tmp) //11.Пока тмп больше "0". Будем записывать число за числом из результата нашего столбца в массив. Десяток за десятком

{

l=k; //12. Тут l будет нашим счетчиком чтоб не k "портить".

res[l]=+tmp % 10;  //13. Записывам(добавляем) еще один десяток

l++; //14. увеличиваем, чтоб след. десяток. добавить....

tmp=tmp/10; //15. уменьшаем tmp на 10. На посл. цифру котор. занесли в результат.

}

k++; //16. увелич. счетчик эл-та рез-та.

     for(j=a.getHeight;j>0;j--) //8. Теперь в нижн. прав. угол.

           {

                 tmp+=a[j][i]; //9. Снизу(!) вверх суммируем ВСЕ числа. Сумма столбика:)

           }

}

return reverse(res);//17. Возвращаем наш результат. Вот он супер массив число. Только надо обернуть его, чтоб правильно записалось:)

}



sum(a);^_0

это С
FalseNegative
(eternalko)
А... И еще все переменные должны быть по нулямsmile.gif В начале программы)

В C - да, в Паскале, - нет, никто никаких неявных присвоений 0 не делает!

(долго очень думает, я так и не дождался результат. Если же больше 250 - даже не компилируется, сразу кидает ошибку, что мало памяти. А все (на сколько я понимаю) из-за двумерного массива.

А дебаггером что, религия пользоваться не позволяет? Хотя сильно подозреваю, что всё дело именно в том, что мой способ (с переменной go_on работает правильно только если доступно больше индексов, чем надо. Иначе он почти наверняка пойдёт на 0, -1, и т.д. индексы.). ((10-значное*10значное) - это наверняка минимум 11-значное число.)

По нехватке памяти... Есть такое ограничение на нединамические массивы и строки, со времён TP. 255 и баста!



   begin

          a1[l]:= a1[l]+p;

          p:= a1[l] div 10;

          a1[l]:= a1[l] mod 10;

          dec(l);

          go_on:= l=0;

     end;
Eternalko
А с этим кодом что?
(eternalko)


program arraysum;

var tosum: array [1...,1...] of Integer; //Почему он должен быть определен?? Вдруг числа оч. большие:)))

actualwidth,actualheight,colsum,k,l: Integer;

aresult: array [1..100] of Integer;

begin



for i := actualwidth downto 1 do

begin





   while colsum do

   begin

    l:=k;

    aresult[l]:=aresult[l]+colsum mod 10;

    colsum:=colsum div 10

    l:=l+1;

   end;



  k:=k+1;



   for j:= actualheight downto 1 do  

   begin

    colsum:=colsum+tosum[j,i];

   end;

end;



end;
DriftKing
FalseNegative, да при го_он 1=0 тоже все работает. Но проблемы не решает. Прога как висла так и виснет, когда массив стает >20 знаков. И зацикливается именно этот фор:


for k:= 1 to max do

     begin

         a[max-i+k]:= a1[k];

         a1[k]:= 0;

     end;

Почему оно зацикливается при массиве с максим. кол-вом елементов 20 и выше, а при 10 и ниже - нет?.
Дебагер юзал, без толку. Увидел только где зацикливается и все. sad.gif
DriftKing
Да...этот фор - это я прижимаю число к правому краю, ибо сразу оно записывает к левому.
Onami
Я так понимаю, у вас до сих пор траблы? Вот Кнут зачем писал книгу свою? Правильно, чтоб не лазили по пекабфорумам в поисках ответов!

NB: пользуйтесь лупой. 8)


По-моему, сопровождать алгоритм кодом на ЯВУ не нужно.
DriftKing
Яву? Где сдесь была ява? или я не в теме? smile.gif
Onami
Яву?

Убило laugh.gif laugh.gif laugh.gif laugh.gif Валялсо laugh.gif

ЯВУ - Язык Высокого Уровня. А Java - это от лукавого.
FalseNegative
(DriftKing)
FalseNegative, да при го_он 1=0 тоже все работает. Но проблемы не решает. Прога как висла так и виснет, когда массив стает >20 знаков. И зацикливается именно этот фор:


for k:= 1 to max do

     begin

         a[max-i+k]:= a1[k];

         a1[k]:= 0;

     end;

Почему оно зацикливается при массиве с максим. кол-вом елементов 20 и выше, а при 10 и ниже - нет?.
Дебагер юзал, без толку. Увидел только где зацикливается и все. sad.gif

А Watch на k, a, a1 ставил? Нет никаких чудных изменений? (чувствую, где-то память испорчена...)

PS: неправильно такие имена переменных юзать. Ты же не говоришь Э! Ыыы. Я Тй. кртк. с. тлнт, тёщ. гон-ра. Зо оч бтр пчт мно.
FalseNegative
(Onami)
А Java - это от лукавого.

:shock: А я ей ем...
DriftKing
Вотч ставил. Ничего подозрительного не видел. Зацикливается в том моменте и все. Ну да ладно. Главное что при меньших работает верно.
Онами, говорю же я за последний месяц башкой поехал biggrin.gif
Волна щас одна - отметить НГ и развести свою даму на секас laugh.gif

Согласен про имена, но это глапуая привычка...и к тому же я страшный леньтяй писать лишние символы smile.gif Я тогда пока пишу имя переменной в 5-7 знаков, могу забыть что хотел в коде подправить laugh.gif
Eternalko
Проверьте мой кодsad.gif
Мне интересно, работает иль нетsad.gif
DriftKing
А ты его с головы писал? Я не пойму, колсум это что? перенос? т.е. принимает значения 0 или 1? почему цыкл пока колсум?
а еще меня эта строка смущает немного: aresult[l]:=aresult[l]+colsum mod 10;
Но помоему работать не будет из-за "while colsum do ..."
Eternalko
(DriftKing)
А ты его с головы писал? Я не пойму, колсум это что? перенос? т.е. принимает значения 0 или 1? почему цыкл пока колсум?
а еще меня эта строка смущает немного: aresult[l]:=aresult[l]+colsum mod 10;
Но помоему работать не будет из-за "while colsum do ..."


Да. С головы. Это первая прогаа паскале :oops:

Можеет так понятней будет



program arraysum;

var tosum: array [1..100,1..100] of Integer;

actualwidth,actualheight,colsum,k,l: Integer;

aresult: array [1..100] of Integer;

begin



for i := actualwidth downto 1 do

begin



   for j:= actualheight downto 1 do  

   begin

    colsum:=colsum+tosum[j,i];

   end;



   while colsum do

   begin

    l:=k;

    aresult[l]:=aresult[l]+colsum mod 10;

    colsum:=colsum div 10

    l:=l+1;

   end;



  k:=k+1;





end;



end;

Внешний for который идет по i перебирае КАЖДЫЙ СТОЛБЕЦ. Колоннуsmile.gif colsum это ColumnSumm. Сумма чисел в каждой колонне.
Допустим она большая и равна не просто 3, а скажем 72453. Тогда мы не можем просто записать тройку а все остальное откинутьsmile.gif Надо каждый разряд отделить и отдельно дописать в след. эл-т матрицы результата

While colsum это цикл, который по разрядам толкает. Пока не растолкает(While colsum aka While colsum >0 smile.gif )Не успокоитсяsmile.gif

А че строка смущает я не знаюsmile.gif
Может так не будетsmile.gif
aresult[l]:=aresult[l]+(colsum mod 10);

Ps. в проге есть маленький жук)
Пока не правил, чтоб понятней было о чем речьsmile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.