[Hochpräziser Algorithmus]|Grundlegender Algorithmus|Addition, Subtraktion, Multiplikation und Division mit hoher Präzision, Brettalgorithmus. |Integer-Hochpräzisionsalgorithmus|Detaillierter Code

Erstens: Welches Problem löst hohe Präzision?

Die sogenannten hochpräzisen Algorithmen lösen tatsächlich einfache Additions-, Subtraktions-, Multiplikations- und Divisionsoperationen, aber warum nennen wir sie eine Klasse von Algorithmen? Gibt es in der C-Sprache nicht verwandte Operatoren, die Operationen ausführen können? Dazu müssen wir wissen, dass Operationen in der C-Sprache durchaus möglich sind, es jedoch bestimmte Einschränkungen gibt. Wir wissen, dass wir beim Ausführen von Operationen verwandte Variablen verwenden müssen, um Daten für Operationen zu speichern. long Die long-Variable ist die größte ganzzahlige Variable und Der maximal erreichbare Wert beträgt nur 10 18. Wenn wir Berechnungen mit größeren Werten durchführen möchten, können wir diese nicht verarbeiten, daher schlagen wir einen hochpräzisen Algorithmus vor.

Hohe Präzision bezieht sich nicht nur auf die Genauigkeit nach unten (Dezimalpunkt nach rechts), sondern auch auf die Genauigkeit nach oben (Dezimalpunkt nach links).

Zweitens hochpräziser Algorithmus

1. Die Idee eines hochpräzisen Algorithmus

Die Algorithmusidee der hochpräzisen Addition, Subtraktion, Multiplikation und Division ist eigentlich dieselbe. Wir können keine Daten verarbeiten, daher müssen wir darüber nachdenken, wie Menschen Daten verarbeiten. Nehmen wir als Beispiel die hochpräzise Addition, wenn wir addieren : Wir verwenden Schritt für Schritt Aus dieser Richtung können wir das Problem mithilfe von Carry lösen. Für die handschriftliche Hinzufügung müssen wir zunächst einen Durchbruch finden und dann die gesamten Daten verarbeiten. Die Kernidee des hochpräzisen Algorithmus besteht darin, die Zahl auf 1 zu reduzieren : Teilen Sie einen sehr langen Wert in einen Wert und führen Sie Operationen an einem Wert durch, sodass unser Problem sehr vereinfacht wird, das heißt, eins ist das Merkmal Operation jedes Algorithmus, wie Addition, Subtraktion, Multiplikation und Division. Die andere ist eine allgemeine Lösung, wie diese hochpräzisen Daten getrennt werden können.

2, Speicherung hochpräziser Daten

Es gibt viele Speichermethoden für hochpräzise Daten, aber um den Vorgang zu vereinfachen, haben wir uns schließlich für die Vektorarray -Speichermethode entschieden. Wenn wir hochpräzise Daten einlesen, müssen wir zunächst den String -Datentyp zum Einlesen verwenden , und dann fügen wir einige Daten nacheinander ein. Beim Einlesen in den Vektor muss sichergestellt werden , dass der Push-Vektor vom Low-Bit zum High-Bit verschoben wird, da nur auf diese Weise die entsprechende Beziehung der Werte hergestellt werden kann gewährleistet, und es ist bequem zu tragen.
Fügen Sie hier eine Bildbeschreibung ein

Der gesamte Vorgang ist relativ einfach, es sollte jedoch beachtet werden, dass die Daten in der Zeichenfolge dieser Operation vor dem Einschieben einige Verarbeitungsschritte erfordern, da die Zahlen in der Zeichenfolge vom Typ „Zeichen“ sind. Was wir eingeben müssen, ist eine Zahl, um Berechnungen durchzuführen. Daher müssen wir einen einfachen str[i] - '0' ausführen und dann fortfahren, nachdem dieser Vorgang abgeschlossen ist.

Ergänzende Vektor-Grundoperationen
Definition: Vektor <Datentyp> Variablenname;
Aufruf: (Index) Start von 0 bis n - 1
Größe: B.size() Rückgabegröße
Push: C.push_back()

Vollständiger Daten-Push-In

#include <iostream>
#include <string>
#include <vector>

using namespace std ;
int main ()
{
    
    
	string a;
	vector <int> A;
	cin >> a; 
	for(int i = a.length() - 1 ; i >= 0 ; i -- )
		A.push_back(a[i] - '0');
		//存储:1.反存储 , 2.减去'0' 

	for(int i = 0 ; i < A.size() ; i ++ )
		cout << A[i] ;
	puts("") ;
	return 0 ;
}

Drei, hochpräzise Addition

1. Ideen für Algorithmen

Zunächst wissen wir, dass wir die Daten in niedriger Reihenfolge gespeichert haben . Wie zerlegen wir diese große Operation in kleine Operationen, um sie zu lösen? Wir müssen eine Lösung aus der ursprünglichen Idee der Addition finden. Wir können die i-te Operation jedes Mal gemäß der Übertragsmethode ausführen, den Übertrag des vorherigen Bits hinzufügen und ihn dann in einem neuen Array speichern. Wenn beide Seiten leer sind, beenden wir diesen Algorithmus. Wenn der Übertrag 1 ist, übertragen wir ein Bit für das Zielarray und geben schließlich das Array zurück, um diesen Vorgang abzuschließen.

Natürlich sollte auch die Ausgabe des Arrays umgekehrt werden.

2, Algorithmuscode

#include <iostream>
#include <vector>
#include <string>

using namespace std ;

vector <int> add(vector<int> &A ,vector<int> &B)
//f1.&取地址运算能加快速度 , 能加上的时候尽量加上.
{
    
    
	int t = 0 ;
	//存数的指针
	vector <int> C;
	for(size_t i = 0 ; i < A.size() || i < B.size() ; i ++ )
	{
    
    
		if(i < A.size()) t += A[i] ;
		if(i < B.size()) t += B[i] ;
		C.push_back(t % 10);
		t /= 10;
	}
	if(t)  C.push_back(1) ;
	return C ;
}

Viertens hochpräzise Subtraktion

1. Ideen für Algorithmen

Nachdem wir etwas über hochpräzise Addition gelernt hatten, stellten wir fest, dass dieser Algorithmus tatsächlich durch so etwas wie einen Zeiger gesteuert wird. Wir verlassen uns auf diesen Zeiger, um unserem Zielarray jedes Mal einen Wert zuzuweisen. Der Schlüssel zur Lösung hochpräziser Probleme liegt tatsächlich in der Verarbeitung Problem mit diesem Zeiger. Wir müssen über diese Subtraktionsoperation nachdenken. Bei der Subtraktionsoperation wissen wir, dass es zwei Operationen gibt: groß-klein und klein-groß . Wie man diese beiden Operationen abschließt, können wir diese beiden in eine umwandeln. Lassen Sie uns zunächst beurteilen, welche ist welche Die beiden Fälle werden dann zu einem der Fälle zur Verarbeitung zusammengefasst. Wir können die Operation der Konvertierung von A – B implementieren . Lassen Sie uns zunächst beurteilen, welche Zahl groß ist.

bool cmp (vector<int> &A , vector<int> &B)
{
    
    
    if(A.size() != B.size()) return A.size() > B.size();

    for(int i = A.size() -  1 ; i >= 0 ;i --)
        if(A[i] != B[i])
            return A[i] > B[i];
        return true ;

}

Nach Abschluss dieser Operation können wir eine Beurteilungszweigstruktur für die Hauptfunktion festlegen, um A > B zu erfüllen. Dann müssen wir die Hauptoperation der Subtraktion abschließen

vector <int> sub(vector <int> &A ,vector<int> &B)
{
    
    
    int t =  0 ;
    //指针为 t ,t代表当前A - B 的值
    vector <int> C;
    for(size_t i = 0 ; i < A.size() ; i ++ )
    {
    
    
        t += A[i] ;
        //完成 + A
        if(i < B.size() ) t -=B[i] ;
        //完成 - B
        C.push_back((t + 10) % 10 );
        if(t >= 0)  t =  0 ;
        else t  =  -1 ;
        //完成为下一位的赋值
    }
    while (C.size() > 1 && C.back() == 0)   C.pop_back() ;
    return C ;
}

Schauen wir uns als Nächstes den Gesamtcode an

#include <iostream>
#include <vector>

using namespace std;

bool cmp (vector<int> &A ,vector<int> &B )
{
    
    
    if(A.size() != B.size() )   return A.size() > B.size() ;
    for(int  i = A.size() - 1; i >=0 ; i -- )
        if(A[i] != B[i])
            return A[i] > B[i] ;
        return true ;
}

vector <int> sub(vector <int> &A , vector <int> &B)
{
    
    
    vector <int> C;
    for(int i = 0 , t = 0;i <= A.size() - 1; i ++ )
    {
    
    
        t = A[i] - t ;
        if(i < B.size() )  t -= B[i];
        C.push_back( ( t + 10 ) % 10 );
        if(t<0) t=1;
        else  t=0;
    }
    while (C.size ()>1 && C.back()==0)  C.pop_back();
    return C;
}

int main ()
{
    
    
    string a , b ;
    vector <int> A ,B ,C ;
    cin >> a >> b ;
    for(int i = a.length() - 1; i >= 0 ; i --)
        A.push_back(a[i] - '0');
    for(int i = b.length() - 1 ; i >= 0 ; i --)
        B.push_back(b[i] - '0');
    if(cmp(A,B))
    {
    
    
        auto C=sub(A,B);
        for(int i=C.size()-1;i>=0;i--) cout << C[i];
    }
    else 
    {
    
    
        auto C=sub(B,A);
       cout<<"-";
        for(int i=C.size()-1;i>=0;i--)  cout<<C[i];
    }
    return 0;
}

Fünf, hochpräzise Multiplikation

1. Ideen für Algorithmen

Im Vergleich zu den ersten beiden kann man sagen, dass die hochpräzise Multiplikation einfacher ist und in etwa die Algorithmusidee der hochpräzisen Addition fortsetzt. Logischerweise kann diese hochpräzise Multiplikation nicht als vollständige hochpräzise Multiplikation angesehen werden. Dies ist ein hochpräziser * Algorithmus mit . Dieser Algorithmus umfasst einen Algorithmus zum Löschen führender Nullen und einen Algorithmus, der einem Zeiger ähnelt, den wir zuvor erwähnt haben. Dieser Zeiger speichert den Wert jeder Multiplikation und gibt das Ende jeder Zeit aus.

2, Code

#include <iostream>
#include <vector>

using namespace std ;

vector<int> mul (vector<int> & A ,int b)
{
    
    
    int t = 0 ;
    //相当于整个题目的指针
    vector <int> B ;
    for(int i = 0 ; i < A.size() || t ; i ++)
    {
    
    
        if(i < A.size()) t += A[i] * b ;
        B.push_back(t % 10);
        t /= 10 ;
    }
    while (B.size() > 1 && B.back() == 0)   B.pop_back();
    return B ;
}

int main ()
{
    
    
    int a ;
    string b ;
    
    vector <int> A , B;
    cin >> b >> a ;

    for(int i = b.length() - 1 ; i >= 0 ; i -- )
        A.push_back(b[i] - '0');
    B = mul(A,a);
    for(int i = B.size() - 1 ;i >= 0 ; i --)
        cout << B[i] ;

    return 0 ;
}

Sechs, hochpräzise Teilung

1. Ideen für Algorithmen

Erstens unterscheidet sich dieser Algorithmus von den vorherigen Algorithmen. Obwohl es sich bei diesem Algorithmus um eine inverse Datenspeicherung handelt, führt er am Ende immer noch Operationen von hohen Bits aus aus. Der gesamte Algorithmus wurde zweimal umgekehrt, außerdem zeigen sein Zeiger und sein Zeiger auf seinen Rest, jede Stufe zeigt auf den Rest jeder Stufe, die Idee ähnelt der Multiplikation

Zusatzwissen: Um führende Nullen zu entfernen, müssen wir
die Umkehrfunktion in der Algorithmus-Header-Datei verwenden (unter Verwendung von Iteratoren).

2. Code

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std ;

vector <int> div(vector <int> &B ,int a ,int &r)
{
    
    
    r = 0 ;
    vector <int> C ;
    for(int i = B.size() - 1 ; i >= 0 ; i -- )
    {
    
    
        r = r * 10 + B[i] ;
        C.push_back(r / a);
        r %= a ;
    }
    reverse(C.begin(),C.end());
    while (C.back() == 0 && C.size() > 1 ) C.pop_back();
    return C ;
}

int main ()
{
    
    
    int  a , r;
    string b ;
    cin >> b >> a ;
    vector <int> B , C;
    for(int i = b.size() - 1 ;  i >= 0 ; i -- )
        B.push_back(b[i] - '0');
    C = div(B , a , r);
    for(int i = C.size() - 1 ;i >= 0 ; i --)
        cout << C[i] ;
    cout << endl  << r << endl; 
    return 0 ;
}

Acho que você gosta

Origin blog.csdn.net/wen030803/article/details/131697834
Recomendado
Clasificación