Не сте регистриран! Регистрирайте се БЕЗПЛАТНО, за да използвате услугите на сайта!

 Квадрат на ''голямо'' цяло число.
Автор  jan (10.01.2005 12:01) съобщение до автора
Погледнат  1974 пъти добави към любими
Оценка добави коментар
Гласове  4 изпрати на приятел
Коментари  (6) абонирай се за C-Cplusplus
     
jan
     
 

//Това е отговор на
// it-place.net > Форум > Задачи > Квадрат и куб на цяло число
//Реализира се алгоритъм за повдигане на "голямо" число на втора степен.
//Оригиналният алгоритъм избягва междинните резултати при това е за
//умножение на две произволни числа(този също). Тук имаме един
//междинен резултат.
//Не се прави проверка за коректност на входа и т.н.
//Коментариите липсват или са минимални, защото:
//1. Това не е точно алгоритъма, който искам да реализирам
//2. Може би ще Ви е интересно да го разгадаете:-)
//Акцентът е върху алгоритъма. Така, че трябва да се внимава какво се
//въвежда:-)
//Компилирана е с g++, с малки изменения върви и на Microsoft C++
//Например, можем да пресметнем:
//z=234234235454352543243242354354363452532423523523523
//z*z=05486567705888506598020681713518889802337323201766038140835736560
//2349397513356435363995449337134331529
//Както се вижда не е реализирано и игнориране на началната 0-ла:-)
//И все пак и тук не могат да се смятат произволно големи число.
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
    //тук съхраняваме числото, което ще повдигаме на квадрат
    vector<char> a;
   
    string aa;
    cout<<"Input number z=";
    cin>>aa;

    //дължина на числото
    const int n=aa.size();
    const int two_n=2*n;
    //Тук ще се помества резултатът
    vector<int> rez(two_n,0);

    for(int i=0;i<n;i++)
    {
        a.push_back(aa[i]-48);
    }

    //начало на алгоритъма
    int k=two_n-1;
    int kk=two_n-1;
        for(int i=n-1;i>=0;i--)
        {
            for(int j=n-1;j>=0;j--)
            {
                rez[k]=rez[k]+a[j]*a[i];
                k--;
            }
            kk--;
            k=kk;
        }   

    int med;
    //формиране на резултата
    for(int i=two_n-1;i>0;i--)
    {
        med=rez[i];
        rez[i]=rez[i]%10;
        med=(med-rez[i])/10;
        rez[i-1]+=med;
    }
    //край на алгоритъма
   
    //извеждане на резултата
    cout<<"z*z=";
    for(int i=0;i<=two_n-1;i++)
        cout<<rez[i];
    cout<<endl;   
    system("PAUSE");   
    return 0;
}



Ключови думи: c C++ c# алгоритъм куб квадрат цяло число умножение




 1 посетител чете този скрипт (0 потребители и 1 гост)  
Активни потребители: ---
   
  

Еmail  
 

Здравей, Jan!

Радвам се, че вече няколко пъти се получават интересни дискусии над твои програмки - продължавай в същия дух! :) Защото именно такива дискусии са от полза на всички ни по пътя да станем по-добри програмисти :)

Можеш да продължиш задачката като напишеш клас BigInteger например, в който енкапсулираш всички функции за работа с големи числа - събиране, изваждане, умножение, деление, степенуване... И можеш да се възползваш от operator overloading механизма на C++, така че тези обекти да могат да се ползват като променливи от вградените типове. Т.е. да можеш да правиш следното например :

BigInteger a, b;
cin >> a >> b;
BigInteger c = a * b;
BigInteger d = 4 + c / 2;
cout << c << d;

Поздрави,
Изида

  Izida на 11.01.2005 09:07

Здравей Izida!

Поправката ти всъщност беше доста уместна, всъщност май това си
прави и оригиналният алгоритъм (макар и не точно в този ред, но горе-долу
същият брой операции).
Самият алгоритъм е много прост, но се разбира най-добре от нагледен
пример. Известен е от доста отдавна (средновековието:-). Има и други
интересни алгоритми, то те май не са толкова подходящи за компютри:-)
Така, че ето и програмката за умножение на две ''големи''  числа.
Както виждаш разликите са съвсем малко:-) А ти вече си разбрала
как работи, така че съм сигурен, че щеше да си го откриеш:-)

#include <iostream>
#include <stdlib.h>
#include <vector>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
    //множители
    vector<char> a,b;
    string aa,bb;
    cout<<"Input first number z1=";
    cin>>aa;
    for(int i=0;i<aa.size();i++)
    {
        a.push_back(aa[i]-48);
    }    

    cout<<"Input second number z2=";
    cin>>bb;
    for(int i=0;i<bb.size();i++)
    {
        b.push_back(bb[i]-48);
    }

    //дължина на множителите
    const int n=aa.size(),m=bb.size();
    //резултат
    vector<int> rez(n+m,0);
   
    //Начало на алгоритъма
    int k=n+m-1;
    int kk=n+m-1;
        for(int i=m-1;i>=0;i--)
        {
            int carry = 0;
            for(int j=n-1;j>=0;j--)
            {
                rez[k]=rez[k]+carry+a[j]*b[i];
                carry = rez[k] / 10;
                rez[k] %= 10;
                k--;
            }
            rez[k] += carry;
            kk--;
            k=kk;
        }   
    //Край на алгоритъма

    cout<<"z1*z2=";
   
    for(int i=0;i<=n+m-1;i++)
        cout<<rez[i];
    cout<<endl;
   
    system("PAUSE");   
    return 0;
}

  jan на 11.01.2005 00:04

Ооооо!
Голям съм заплес:-)
Това е защото опростих по-сложният алгоритъм (за умножение на две големи числа:-)
Благодаря:-)

  jan на 10.01.2005 22:57

Чакам новия алгоритъм ;)

Иначе този може да се подобри според мен като се премахне нуждата от втория цикъл и смятането на преноса стане в основния цикъл ето така :

    for(i=n-1;i>=0;i--)
    {
        int carry = 0;
        for(int j=n-1;j>=0;j--)
        {
// взима се предвид и преноса
            rez[k]=rez[k]+carry+a[j]*a[i];
            carry = rez[k] / 10;
            rez[k] %= 10;
            k--;
        }
// добавяне на преноса
        rez[k] += carry;
        kk--;
        k=kk;
    }

Поздрави,
Изида

  Izida на 10.01.2005 16:22

Да. Така е! Не правя проверка! Но има по-добър алгоритъм (поне така си мисля:-). Този е негов производен. И ако го напиша ще изнеса всичко в отделна функция. Тогава ще направя и проверката:-) Интересното е, че този алгоритъм може да се обърне за деление на ''големи'' числа.

  jan на 10.01.2005 15:49

Добра идея! Така можеш да извършваш повдигане на квадрат на много големи числа ;)

Обаче я пробвай да намериш квадрата на 's'. Според програмата ти отговорът е 09. Пропуснал си да проверяваш дали въведените символи са числа преди да ги записваш във вектора.

Поздрави,
Изида

  Izida на 10.01.2005 13:52

 

 
  • Интересно от Софтуер
 
  • Интересно от myLINKS
 
 
 
 



IT-PLACE.NET © 2004 - 2008