Odejmowanie pisemne - tablice

Odpowiedz Nowy wątek
2011-11-20 21:05

Rejestracja: 8 lat temu

Ostatnio: 4 lata temu

0

Witam. Chcę napisać algorytm odejmowania pisemnego. Przygotowałem swój kod, ale nie działa on do końca dobrze. Poprawnie odejmuje 2 pierwsze liczby, ale potem coś się psuje. Domyślam się, że chodzi o zmienną diff i przenoszenia dziesiątek do mniejszych liczb, np. z cyfry dziesiątek na cyfrę jedności. Możecie zerknąć i podpowiedzieć, ewentualnie napisać poprawioną wersję?

#include <iostream>

using namespace std;

void wypisz(int arg[], int size)
{
    int n=0;
    while (arg[n] == 0)
    {
        cout<<"0";
        n++;
    }

     for (int i = n; i<= size; i++)
    {
        cout<<arg[i];
    }
    cout<<endl;
}

void wczytaj (int size, int length, int arg[])
{
    for (int i=0; i<=(size-length); i++)
    {
        arg[i] = 0;
    }
    for (int i=(size+1-length); i<=size; i++)
    {
        cout << "Podaj kolejna cyfre: ";
        cin >> arg[i];
    }
}

void dodaj (int arg1[], int arg2[], int length1, int length2, int size)
{
        int suma;
        int *T = new int[size];

        for (int i=0; i<=size; i++)
        {
            T[i] = 0;
        }
        for (int i=size; i>=0; i--)
        {
            suma = arg1[i] + arg2[i] + T[i];
            if (suma>9) T[i-1] = T[i-1] + 1;
            T[i] = suma % 10;
        }

        wypisz(arg1, size);
        wypisz(arg2, size);
        wypisz(T, size); //wynik

        delete [] T;
}

void odejmij (int arg1[], int arg2[], int length1, int length2, int size)
{
 //tablica z wynikiem
 int *T = new int[size];
 for (int i=0; i<=size; i++)
        {
            T[i] = 0;
        }
 int num=0;
 int diff;

 if (length1 > length2)
 {
     for (int i=size; i> size-length1; i--)
     {
         if (arg1[i] >= arg2[i]) //jesli mozna odjac od siebie
         {
             T[i] = arg1[i] - arg2[i];
         }
         else//w przeciwnym razie nalezy szukac jakiejs liczby, z ktorej mozna pobrac wartosc
         {
            for (int j=i-1; j> size-length1; j--)
            {
                if (arg1[j] > 0) //jesli znajdzie liczbe wieksza od zera, na lewo od liczby ktora chcemy odjac to ma ona numer j
                {
                    arg1[j]--;//zmniejszamy ta liczbe o 1
                    diff = i - j-1; //odleglosc liczby z ktorej pobieramy 1 od liczby odejmowanej
                    for (int k=j; k<i; k++) //tutaj jest przenoszenie tej jedynki, wymaga poprawy.
                    {
                        arg1[k+1] = arg1[k+1] + (10-diff);
                        diff--;
                    }
                }
            }
            T[i] = arg1[i] - arg2[i];
         }
         wypisz(T, size); //wynik
     }
 //wypisz(arg1, size); 
 //wypisz(arg2, size); 
 //wypisz(T, size); //wynik
 }

        delete [] T;
}

int main()
{
    int maxw1, maxw2;
    int size = 60;

    cout << "Cyfry wprowadzaj od najwiekszych az do cyfr jednosci."<<endl;
    cout << "Pierwsza liczba: "<<endl;
    cout << "Ilosc cyfr: ";
    cin >> maxw1;
    int tab1[size];
    wczytaj(size, maxw1, tab1);

    cout << "Druga liczba: " << endl;
    cout << "Ilosc cyfr: ";
    cin >> maxw2;
    int tab2[size];
    wczytaj(size, maxw2, tab2);

    wypisz(tab1, size);
    wypisz(tab2, size);

    //dodaj(tab1, tab2, maxw1, maxw2, size);
    odejmij(tab1, tab2, maxw1, maxw2, size);
    return 0;
}
edytowany 2x, ostatnio: zwierzak1337, 2011-11-20 21:20

Pozostało 580 znaków

2011-11-21 11:58

Rejestracja: 12 lat temu

Ostatnio: 1 dzień temu

0

#co jeśli length1==length2 (lub length1<length2)?
#po co tyle tych zagnieżdżonych for-ów? Widzę ich aż trzy! To zniechęca do analizowania co właściwie zrobiłeś. Do odejmowania wystarczy tylko jeden for.
#Jak piszesz w C++ to czemu nie używasz klas? To znacznie uprościło by ci życie


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Pozostało 580 znaków

2011-11-21 14:55

Rejestracja: 8 lat temu

Ostatnio: 4 lata temu

0

Jestem jeszcze stosunkowo początkujący w C++. O klasach wiem trochę z C#, wydaje mi się, że tutaj jest podobnie. Wydawało mi się również, że klasy to tylko forma zapisu, skracająca pewne operacje: powiedzmy klasa matematyka a w niej metoda odejmowanie. Nie ułatwi mi to w żaden sposób napisania samego algorytmu, prawda? Co do forów, pisałem tak jak mi się wydawało, że będzie słusznie. Przy każdym ważniejszym fragmencie dodałem opis co to w założeniu powinno robić. Nie przychodzi mi do głowy sposób zapisania tego w jednej pętli for, dlatego proszę Was o pomoc z tym zagadnieniem. No i na końcu, co jeśli length1==length2 - to miałem zostawić sobie na koniec, gdy już napiszę podstawowy algorytm, to wtedy martwił bym się szczególnymi przypadkami, to jest, np. gdy length1==length2 szacowaniem wartosci liczby, porównując kolejne cyfry.

edytowany 2x, ostatnio: zwierzak1337, 2011-11-21 14:56

Pozostało 580 znaków

2011-11-21 15:23

Rejestracja: 12 lat temu

Ostatnio: 1 dzień temu

0

Umiesz odejmować pisemnie? Na pewno tak. Teraz twoim zdaniem jest jedynie zapisanie sposobu tego odejmowania za pomocą C++.
Czy jak odejmujesz już 6 cyfrę to odwołujesz się do cyfry pierwszej? NIE!

Pseudo kod:

iteruj po cyfrach zaczynając od jedności
   odejmij od siebie odpowiednie cyfry i potencjalne "przeniesienie"
   jeśli wynik jest ujemny to dodaj 10 i zapamiętaj "przeniesienie"

"przeniesienie" (z ang. "carry") oznacza pożyczenie jedności ze starszej cyfry.

PS. Po co ci ten size w odejmowaniu? To możesz łatwo obliczyć na podstawie innych argumentów.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.

Pozostało 580 znaków

2011-11-21 15:45

Rejestracja: 8 lat temu

Ostatnio: 4 lata temu

0

Trochę zmieniłem swoją wersję, tak że działa gdy length1 > length2. Zmieniłem tylko fragment przenoszenia wartosci do cyfry odejmowanej. No ale domyślam się, że Twój sposób nie wymaga założenia że length1 > length2?

Nie rozumiem troche tego, "i potencjalne przeniesienie". W tym wypadku wystarczy, że będę pożyczał wartość od cyfry starszej o jeden poziom? Np. do jedności biorę z dziesiątek, do setek z tysięcy itp?

Co do tego size, mówiłem że jeszcze nie wszystko mam opanowane. Kod ma służyć celom edukacyjnym więc nie musi być doskonały. Domyślam się, że można łatwiej wyciągnąć rozmiar tablicy, ale zrobiłem tak jedynie dla własnej wygody.

Tutaj moja wersja:

#include <iostream>

using namespace std;

void wypisz(int arg[], int size)
{
    int n=0;
    while (arg[n] == 0)
    {
        cout<<" ";
        n++;
    }

     for (int i = n; i<= size; i++)
    {
        cout<<arg[i];
    }
    cout<<endl;
}

void wczytaj (int size, int length, int arg[])
{
    for (int i=0; i<=(size-length); i++)
    {
        arg[i] = 0;
    }
    for (int i=(size+1-length); i<=size; i++)
    {
        cout << "Podaj kolejna cyfre: ";
        cin >> arg[i];
    }
}

void dodaj (int arg1[], int arg2[], int length1, int length2, int size)
{
        int suma;
        int *T = new int[size];

        for (int i=0; i<=size; i++)
        {
            T[i] = 0;
        }
        for (int i=size; i>=0; i--)
        {
            suma = arg1[i] + arg2[i] + T[i];
            if (suma>9) T[i-1] = T[i-1] + 1;
            T[i] = suma % 10;
        }

        wypisz(arg1, size); //dzielna
        wypisz(arg2, size); //dzielnik
        wypisz(T, size); //wynik

        delete [] T;
}

void odejmij (int arg1[], int arg2[], int length1, int length2, int size)
{
 //tablica z wynikiem
 int *T = new int[size];
 for (int i=0; i<=size; i++)
{
    T[i] = 0;
}

 if (length1 > length2)
 {
     for (int i=size; i> size-length1; i--)
     {
         if (arg1[i] >= arg2[i]) //jesli mozna odjac od siebie
         {
             T[i] = arg1[i] - arg2[i];
         }
         else//w przeciwnym razie nalezy szukac jakiejs liczby, z ktorej mozna pobrac wartosc
         {
            for (int j=i-1; j> size-length1; j--)
            {
                if (arg1[j] > 0) //jesli znajdzie liczbe wieksza od zera, na lewo od liczby ktora chcemy odjac to ma ona numer j
                {
                    arg1[j]--;//zmniejszamy ta liczbe o 1
                    for (int k=j; k<i-1; k++) //tutaj jest przenoszenie tej jedynki
                    {
                        arg1[k+1] += 9; //wszystkie liczby po drodze zwiekszamy o 9, bo od razu bierzemy 1 do nastepnej obok
                    }
                    arg1[i] +=10; //liczbe odejmowana zwiekszamy o 10
                    T[i] = arg1[i] - arg2[i];
                    break; //dzieki temu funkcja dobrze dziala!!!
                }

            }

         }

     }
 wypisz(T, size); //wynik
 }

        delete [] T;
}

int main()
{
    int maxw1, maxw2;
    int size = 60;

    cout << "Cyfry wprowadzaj od najwiekszych az do cyfr jednosci."<<endl;
    cout << "Wprowadz dzielna: "<<endl;
    cout << "Ilosc cyfr: ";
    cin >> maxw1;
    int tab1[size];
    wczytaj(size, maxw1, tab1);

    cout << "Wprowadz dzielnik: " << endl;
    cout << "Ilosc cyfr: ";
    cin >> maxw2;
    int tab2[size];
    wczytaj(size, maxw2, tab2);

    wypisz(tab1, size);
    wypisz(tab2, size);

    //dodaj(tab1, tab2, maxw1, maxw2, size);
    odejmij(tab1, tab2, maxw1, maxw2, size);
    return 0;
}
edytowany 2x, ostatnio: zwierzak1337, 2011-11-21 15:50

Pozostało 580 znaków

Odpowiedz

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0