2862 afișări Andrei Visalon (Prekzursil) 01.05.2022 www.pbinfo.ro
Etichete: nicio etichetă

Am definit o clasa care permite calcului cu numere mari implementata cu templated string si pentru a permite o accesibilitate user-friendly, operatori aritmetici au fost de asemenea adaptati pentru a permite calculul. Din nefericire avand in vedere ca C++ este limitat de arhitectura procesorului pentru a executa calcule in anumite intervale, consider ca va fi de folos aceasta clasa.

Avem header-ul unde se afla definitile functilor constructorul si destructorul.

#pragma once
#include<string>
#include<algorithm>
#include<vector>
#include<utility>
#include<iostream>
using namespace std;

class BigInt {
private:
    string s;

    bool mai_mic_sau_egal(string s,string ss);
    bool mai_mic(string s,string ss);
    bool mai_mare(string s, string ss);
    bool mai_mare_sau_egal(string s,string ss);
    string sx(string s,string ss);
    string dx(string s,string ss);
    string px(string s,string ss);
    string pow(string s,string ss);
    pair<string,string> ddx(string s,string ss);
    void convert_to_int();
    void convert_to_float();
public:
    BigInt(string n);
    ~BigInt()=default;
    bool operator<(BigInt ss);
    bool operator<=(BigInt ss);
    bool operator==(BigInt ss);
    bool operator>(BigInt ss);
    bool operator>=(BigInt ss);
    void operator=(string ss);
    void operator=(BigInt ss);
    string operator+(BigInt ss);
    string operator-(BigInt ss);
    string operator*(BigInt ss);
    string operator^(BigInt ss);
    operator int();
    operator float();

    //if you are sure the number is within c++ bounds you can convert it to the wanted value
    int to_int();
    double to_double();
    long long to_ll();
    unsigned long long to_ull();

    friend ostream& operator<<(ostream& os, BigInt &s);
    friend istream& operator>>(istream& is, BigInt &s);
    pair<string,string> operator/(BigInt ss); //returns a pair containing on first the quotient and on second the reminder of the division
    string sqrt();

};


Iar aici implementarea functilor impreuna cu functile de tip get/set.

#include "BigInt.h"

BigInt::BigInt(string n){
    s=n;
}

string BigInt::operator+(BigInt ss) {
    return sx(s,ss.s);
}

string BigInt::operator*(BigInt ss) {
    return px(s,ss.s);
}

void BigInt::operator=(string ss) {
    s=ss;
}

string BigInt::operator-(BigInt ss) {
    return dx(s,ss.s);
}

bool BigInt::operator<(BigInt ss) {
    return mai_mic(s,ss.s);
}

string BigInt::sqrt() {
    string rezerve=s;
    string rez,temp,aux,p;
    int ok=0,k,o=0,c=0,l;
    if(s[0]=='-')
        ok=1,s.erase(s.begin()+0);
    if(s.find('.')==-1)
    {
        l=s.size();
        if(s.size()%2)
            k=s.size()/2+1;
        else
            k=s.size()/2;
    }
    else
    {
        k=s.find('.'),s.erase(s.begin()+k);
        l=k;
        if(k%2)
            k=k/2+1;
        else
            k/=2;
    }
    s+="0000000000000000";
    if(l%2)
    {
        o=1;
        temp+=s[0];
        while(c<9)
        {
            aux+=to_string(c++);
            p=px(aux,aux);
            if(!mai_mic_sau_egal(p,temp))
                break;
            aux.pop_back();
        }
        rez+=--aux[0];
        p=dx(temp,px(aux,aux));
        while(p[0]=='0')
            p.erase(p.begin()+0);
        if(p!="")
            temp=p;
        else
            temp="";
    }
    for(int i=o;i<s.size();)
    {
        c=-1;
        temp+=s[i++];
        temp+=s[i++];
        if(temp=="00")
        {
            rez+='0';
            temp="";
            continue;
        }
        if(aux!="")
            aux=px(rez,"2");
        else
        {
            while(c<9)
            {
                c++;
                if(c==10)
                {
                    aux+=to_string(--c);
                    p=px(aux,aux);
                    break;
                }
                else
                    aux+=to_string(c);
                p=px(aux,aux);
                if(!mai_mic_sau_egal(p,temp))
                {
                    if(c==9)
                        c--;
                    break;
                }
                if(c!=9)
                    aux.pop_back();
            }
            if(c==9)
                rez+=to_string(c);
            else
                rez+=--aux[0];
            p=dx(temp,px(aux,aux));
            while(p[0]=='0')
                p.erase(p.begin()+0);
            if(p!="")
                temp=p;
            else
                temp="";
            continue;
        }
        while(c<9)
        {
            c++;
            if(c==10)
            {
                aux+=to_string(--c);
                p=px(aux,to_string(c));
                break;
            }
            else
                aux+=to_string(c);
            p=px(aux,to_string(c));
            if(!mai_mic_sau_egal(p,temp))
            {
                if(c==9)
                    c--;
                break;
            }
            if(c!=9)
                aux.pop_back();
        }
        if(c==9)
            rez+=to_string(c);
        else
            rez+=--aux[aux.size()-1];
        c=aux[aux.size()-1]-'0';
        p=dx(temp,px(aux,to_string(c)));
        while(p[0]=='0')
            p.erase(p.begin()+0);
        if(p!="")
            temp=p;
        else
            temp="";
        if(rez.size()-k>8 && k<rez.size())
            break;
    }
    rez.insert(rez.begin()+k,'.');
    c=rez.find('.');
    while(rez.size()-1-c>8)
        rez.pop_back();
    if(ok)
        rez+='i';
    s=rezerve;
    return rez;
}

string BigInt::sx(string s,string ss) {
    int ls=0,lss=0,o1=0,o2=0,lmax,len;
    if(s.find('.')!=-1)
        ls=s.find('.'),o1=1;
    if(ss.find('.')!=-1)
        lss=ss.find('.'),o2=1;
    lmax=max(ls,lss);
    len=max(s.size(),ss.size());
    if(o1)
    {
        s.erase(s.begin()+ls),ls--;
        ls=s.size()-1-ls;
    }
    if(o2)
    {
        ss.erase(ss.begin()+lss),lss--;
        lss=ss.size()-1-lss;
    }
    len=max(s.size(),ss.size());
    if(ls>lss)
        for(int i=1;i<=ls-lss;i++)
            ss+='0';
    else
    if(lss>ls)
        for(int i=1;i<=lss-ls;i++)
            s+='0';
    int t=0;
    if (s.length()>ss.length())
        swap(s,ss);
    string str="";
    int n1=s.length(),n2=ss.length();
    int dif=n2-n1;
    for(int i=n1-1;i>=0;i--)
    {
        int sum=((s[i]-'0')+(ss[i+dif]-'0')+t);
        str.push_back(sum%10+'0');
        t=sum/10;
    }
    for(int i=n2-n1-1;i>=0;i--)
    {
        int sum=((ss[i]-'0')+t);
        str.push_back(sum%10+'0');
        t=sum/10;
    }
    if(t)
        str.push_back(t+'0');
    reverse(str.begin(),str.end());
    if(ls || lss)
        str.insert(str.begin()+lmax+(str.size()-len),'.');
    return str;
}

string BigInt::dx(string s,string ss) {
    int ls=0,lss=0,o1=0,o2=0,lmax,len;
    if(s.find('.')!=-1)
        ls=s.find('.'),o1=1;
    if(ss.find('.')!=-1)
        lss=ss.find('.'),o2=1;
    lmax=max(ls,lss);
    len=max(s.size(),ss.size());
    if(o1)
    {
        s.erase(s.begin()+ls),ls--;
        ls=s.size()-1-ls;
    }
    if(o2)
    {
        ss.erase(ss.begin()+lss),lss--;
        lss=ss.size()-1-lss;
    }
    len=max(s.size(),ss.size());
    if(ls>lss)
        for(int i=1;i<=ls-lss;i++)
            ss+='0';
    else
    if(lss>ls)
        for(int i=1;i<=lss-ls;i++)
            s+='0';
    int ok=0;
    if(mai_mic_sau_egal(s,ss) && s!=ss)
        swap(s,ss),ok=1;
    string str = "";
    if(s[0]=='0')
        return "0";
    int n1=s.length(),n2=ss.length();
    int dif=n1-n2;
    int t=0;
    for(int i=n2-1;i>=0;i--)
    {
        int sub=((s[i+dif]-'0')-(ss[i]-'0')-t);
        if(sub<0)
            sub+=10,t=1;
        else
            t=0;
        str.push_back(sub+'0');
    }
    for(int i=n1-n2-1;i>=0;i--)
    {
        if(s[i]=='0'&&t)
        {
            str.push_back('9');
            continue;
        }
        int sub=((s[i]-'0')-t);
        if (i>0||sub>0)
            str.push_back(sub+'0');
        t=0;
    }
    reverse(str.begin(),str.end());
    if(ls || lss)
        str.insert(str.begin()+lmax+(str.size()-len),'.');
    while(str[0]=='0' && str.size()>1)
        str.erase(str.begin()+0);
    if(ok)
        str.insert(str.begin()+0,'-');
    return str;
}

string BigInt::px(string s,string ss) {
    int ls=0,lss=0,o1=0,o2=0,ls1=0,ls2=0,lmax;
    if(s.find('.')!=-1)
        ls=s.find('.'),o1=1,ls1=ls;
    if(ss.find('.')!=-1)
        lss=ss.find('.'),o2=1,ls2=lss;
    if(o1)
        ls1=s.size()-1-ls1;
    if(o2)
        ls2=ss.size()-1-ls2;
    lmax=ls1+ls2;
    if(o1)
    {
        s.erase(s.begin()+ls),ls--;
        ls=s.size()-1-ls;
    }
    if(o2)
    {
        ss.erase(ss.begin()+lss),lss--;
        lss=ss.size()-1-lss;
    }
    if(ls>lss)
        for(int i=1;i<=ls-lss;i++)
            ss+='0';
    else
    if(lss>ls)
        for(int i=1;i<=lss-ls;i++)
            s+='0';
    int n1=s.size();
    int n2=ss.size();
    if(n1==0||n2==0)
        return "0";
    vector<int> rez(n1+n2,0);
    int i_n1=0;
    int i_n2=0;
    for(int i=n1-1;i>=0;i--)
    {
        int t=0;
        int n1=s[i]-'0';
        i_n2=0;
        for(int j=n2-1;j>=0;j--)
        {
            int n2=ss[j]-'0';
            int sum=n1*n2+rez[i_n1+i_n2]+t;
            t=sum/10;
            rez[i_n1+i_n2]=sum%10;
            i_n2++;
        }
        if(t>0)
            rez[i_n1+i_n2]+=t;
        i_n1++;
    }
    int i=rez.size()-1;
    while(i>=0 && rez[i]==0)
        i--;
    if(i==-1)
        return "0";
    string sss="";
    while(i>=0)
        sss+=to_string(rez[i--]);
    if(ls1 || ls2)
        sss.insert(sss.begin()+(sss.size()-1-lmax),'.');
    return sss;
}

bool BigInt::mai_mic_sau_egal(string s,string ss) {
    int n1=s.length(),n2=ss.length();
    if(n1<n2)
        return true;
    if(n1>n2)
        return false;

    for(int i=0;i<n1;i++)
    {
        if(s[i]<ss[i])
            return true;
        else
        if(s[i]>ss[i])
            return false;
    }
    return true;
}

void BigInt::operator=(BigInt ss) {
    s=ss.s;
}

pair<string,string> BigInt::ddx(string s, string ss) {
    string rest="0";
    int m=2,ls=0,lss=0,o1=0,o2=0,p1=0,p2=0;
    if(s[0]=='-' || ss[0]=='-')
    {
        m=1;
        if(s[0]=='-' && ss[0]!='-')
            p1=1;
        if(s[0]!='-' && ss[0]=='-')
            p2=1;

    }
    if(s[0]=='-' && ss[0]=='-')
        m=0;
    if(s[0]=='-')
        s.erase(s.begin()+0);
    if(ss[0]=='-')
        ss.erase(ss.begin()+0);
    if(s.find('.')!=-1)
        ls=s.find('.'),o1=1;
    if(ss.find('.')!=-1)
        lss=ss.find('.'),o2=1;
    if(o1)
    {
        s.erase(s.begin()+ls),ls--;
        ls=s.size()-1-ls;
    }
    if(o2)
    {
        ss.erase(ss.begin()+lss),lss--;
        lss=ss.size()-1-lss;
    }
    if(ls>lss)
        for(int i=1;i<=ls-lss;i++)
            ss+='0';
    else
    if(lss>ls)
        for(int i=1;i<=lss-ls;i++)
            s+='0';
    if(ss=="1")
    {
        return make_pair(s+".000000","0");
    }
    if(s=="0")
    {
        return make_pair("0.000000","0");
    }
    string rez;
    if(mai_mic(s,ss))
        rez="0.";
    if(mai_mic(s,ss))
        rest=s;
    while(mai_mic(s,ss))
    {
        s+='0';
        if(!mai_mic(s,ss) || (rez.size()-1-rez.find('.')==6 && rez.find('.')!=-1))
            break;
        rez+='0';
    }
    if(rez.find('.')!=-1)
    {
        if(rez.size()-1-rez.find('.')==6)
            return make_pair(rez,rest);
        else
        if(rez.size()-1-rez.find('.')<6 && rez.find('.')!=-1)
        {
            string temp;
            while(rez.size()-1-rez.find('.')<6)
            {
                int ap=0;
                while(!mai_mic(s,ss))
                    s=dx(s,ss),ap++;
                rez+=to_string(ap);
                s+='0';
            }
            return make_pair(rez,rest);
        }
    }
    string temp;
    int j,k=s.size(),ap=0;
    s+="000000";
    for(int i=0;i<s.size() && mai_mic(temp,ss);i++)
        temp+=s[i],j=i+1;
    while(!mai_mic(temp,ss))
        temp=dx(temp,ss),ap++;
    rez+=to_string(ap);
    for(;j<s.size();j++)
    {
        if(rez.find('.')!=-1 && rez.size()-1-rez.find('.')==6)
        {
            if(m==1)
                rez.insert(rez.begin()+0,'-');
            if(((p1 && !p2) || !m) && rest!="0")
                rest.insert(rest.begin()+0,'-');
            return make_pair(rez,rest);
        }
        ap=0;
        if(j==k)
        {
            rez+='.';
            rest=temp;
            ls=max(ls,lss);
            if(ls)
            {
                rest.insert(rest.begin()+rest.size()-ls,'.');
                if(rest[0]=='.')
                    rest.insert(rest.begin(),'0');
            }
        }
        if(temp[0]=='0')
            temp="",temp+=s[j];
        else
            temp+=s[j];
        if(temp[0]=='0')
        {
            rez+='0';
            continue;
        }
        while(mai_mic(temp,ss) && j<s.size())
        {
            rez+='0',temp+=s[++j];
            if(rez.size()-1-rez.find('.')==6 && rez.find('.')!=-1)
            {
                if(m==1)
                    rez.insert(rez.begin()+0,'-');
                if(((p1 && !p2) || !m) && rest!="0")
                    rest.insert(rest.begin()+0,'-');
                return make_pair(rez,rest);
            }
        }
        while(!mai_mic(temp,ss))
            temp=dx(temp,ss),ap++;
        rez+=to_string(ap);
    }
    if(m==1)
        rez.insert(rez.begin()+0,'-');
    if(((p1 && !p2) || !m) && rest!="0")
        rest.insert(rest.begin()+0,'-');
    return make_pair(rez,rest);
}

pair<string, string> BigInt::operator/(BigInt ss) {
    return ddx(s,ss.s);
}

bool BigInt::mai_mic(string s, string ss) {
    int n1=s.length(),n2=ss.length();
    if(n1<n2)
        return true;
    if(n1>n2)
        return false;

    for(int i=0;i<n1;i++)
    {
        if(s[i]<ss[i])
            return true;
        else
        if(s[i]>ss[i])
            return false;
    }
    return false;
}

bool BigInt::operator<=(BigInt ss) {
    return mai_mic_sau_egal(s,ss.s);
}

bool BigInt::operator==(BigInt ss) {
    return s==ss.s;
}

bool BigInt::mai_mare(string s, string ss) {
    int n1=s.length(),n2=ss.length();
    if(n1<n2)
        return false;
    if(n1>n2)
        return true;

    for(int i=0;i<n1;i++)
    {
        if(s[i]<ss[i])
            return false;
        else
        if(s[i]>ss[i])
            return true;
    }
    return false;
}

bool BigInt::mai_mare_sau_egal(string s, string ss) {
    int n1=s.length(),n2=ss.length();
    if(n1<n2)
        return false;
    if(n1>n2)
        return true;

    for(int i=0;i<n1;i++)
    {
        if(s[i]<ss[i])
            return false;
        else
        if(s[i]>ss[i])
            return true;
    }
    return true;
}

bool BigInt::operator>(BigInt ss) {
    return mai_mare(s,ss.s);
}

bool BigInt::operator>=(BigInt ss) {
    return mai_mare_sau_egal(s,ss.s);
}

string BigInt::pow(string s, string ss) {
    if(ss=="0")
        return "1";
    string rez="1";
    for(string i="1"; mai_mic_sau_egal(i,ss);i=sx(i,"1"))
        rez=px(rez,s);
    return rez;
}

string BigInt::operator^(BigInt ss) {
    return pow(s,ss.s);
}

void BigInt::convert_to_int() {
    int point=s.find('.');
    if(point!=-1)
        s.resize(point);
}

void BigInt::convert_to_float() {
    int point=s.find('.');
    if(point==-1)
        s+='.';
    for(int i=1;i<=15;i++)
        s+='0';
}

BigInt::operator int() {
    convert_to_int();
    return 0;
}

BigInt::operator float() {
    convert_to_float();
    return 0;
}

ostream &operator<<(ostream &stream, BigInt& ss) {
    cout<<ss.s;
    return stream;
}

istream &operator>>(istream &is, BigInt& ss) {
    is>>ss.s;
    return is;
}

int BigInt::to_int() {
    return stoi(s);
}

double BigInt::to_double() {
    return stod(s);
}

long long BigInt::to_ll() {
    return stoll(s);
}

unsigned long long BigInt::to_ull() {
    return stoull(s);
}

Si programul driver cu exemple demo de test.

#include<bits/stdc++.h>
#include "BigInt.h"
using namespace std;

int main()
{

    BigInt s("400.5");
    // or s=400 is the same either by assignation or by constructor
    BigInt ss("50");
    cout<<s+ss<<endl;
    cout<<s-ss<<endl;
    cout<<s*ss<<endl;
    pair<string,string> p=s/ss;
    cout<<p.first<<" "<<p.second<<endl;
    cout<<s.sqrt()<<endl;

    s="3.5";
    s.operator int();
    cout<<s<<endl;
    s.operator float();
    cout<<s<<endl;

    s="3";
    ss="3";
    cout<<(s^ss)<<endl;
    ss=s;
    cin>>s;
    cout<<s;

    cout<<s.to_double();
}

End


Probleme ataşate

Nr. Problema Clasa Dificultate Operații I/O
1 #2332 - primXXL 9 medie fișiere
2 #2393 - SumaXXL 9 medie fișiere
3 #2890 - Base Converter 10 dificilă fișiere
4 #3054 - PrimeXXL 10 dificilă fișiere
5 #3053 - EvenOddXXL 10 ușoară fișiere
6 #2928 - SqrtXXL 10 dificilă consola
7 #2689 - PalXXL 9 medie consola
8 #2410 - ProdusXXL 9 medie fișiere
2862 afișări Andrei Visalon (Prekzursil) 01.05.2022 www.pbinfo.ro