Kalkulator na 2 listach

0

Witam. Mam do napisania kalkulator który nie jest ograniczony zmiennymi a pamięcią. W sensie kalkulator na listach. Mam problem z tymi listami,ponieważ nie wiem jak mam poszczególne elementy 2 list dodawać do siebie,mnożyć dzielić i odejmować...Tworzę liste odwrotną żeby łatwiej było operować w przyszłości na poszczególnych elementach, ale coś mi nie wychodzi... Pytanie jest takie: co musze poprawić żeby chociaż dodawanie zaczęło działać? Dodam że nie ogarniam klas... także jakieś dzikie funkcje na klasach to dla mnie czarna magia...

#include <iostream>
#include <stdio.h>
#include<stdlib.h>
#include <conio.h>
using namespace std;
     
struct element
	{
            char cyfra;
            struct element *next;
    };
struct element *nowy_element(char d)
	{
            struct element *wsk; //wskaznik pomocniczy
            wsk=new element;
            wsk->cyfra=d;
            wsk->next=NULL; //wskaźnik wskazuje na null, czyli tam gdzie nic nie ma
            return wsk;
    }
     
struct element *add_element(struct element *poczatek, struct element *nowy)
	{
            nowy->next=poczatek;
            return nowy;
    }
     
char wczytujemy()
{
    struct element *poczatek1, *poczatek2,*poczatek3,*curr1,*curr2,*curr3;//dwie listy, więc dwa oddzielne początki
    poczatek1 = poczatek2 = poczatek3 = NULL; //zerujemy początki, staną się one końcami swoich list
    char d,e,f;
	int state;
     
    cout<<" WPISZ liczbe pierwsza ";
    do
	{
            d=getchar();
            poczatek1=add_element(poczatek1, nowy_element(d));
     
    }
	while(d!='\n');
    cout<<" WPISZ liczbe druga ";
    do
	{
        d=getchar();
        poczatek2=add_element(poczatek2,nowy_element(d));
    }
	while(d!='\n');
    cout<< endl;
    element *temp1=poczatek1; ///poczatek wypisywania elementow

    cout<<endl;
    element *temp2=poczatek2; ///poczatek wypisywania elementow
	
	cout<<endl;
	
	element *temp3=poczatek3; 
	//funkcja dodawania:
	while((temp1&&temp2)!=NULL)
	{
		if((temp1->cyfra)+(temp2->cyfra)>=10)
		{
				temp3->cyfra=(temp1->cyfra)+(temp2->cyfra);
				temp3->cyfra%10;
				poczatek3=add_element(poczatek3, nowy_element(temp3->cyfra));
				temp1=temp1->next;
				temp1->cyfra+1;
		}
		else
		
				poczatek3=add_element(poczatek3, nowy_element(temp3->cyfra));
				temp1=temp1->next;
		                temp2=temp2->next;
		                temp3=temp3->next;

	}
		
	///poczatek wypisywania elementow
	cout<<"LICZBY DODANE= ";
	while(temp3!=NULL)
    {
		cout<<temp3->cyfra;
        temp3=temp3->next;
    }
    return 0;
}
void dodaj(char wczytujemy())
{
	 wczytujemy();
};
int main()
{
	char (*lista1)()=wczytujemy;
    dodaj(lista1);
    system("pause");
    return 0;
}
0

ok,ok.. Jak brzmi zadanie? Po co Ci dwie listy? Co jest w pierwszej a co w drugiej?
Skoro nie umiesz programować, to po co pchasz coś na siłę?Co chciałeś tu osiągnąć?

char (*lista1)()=wczytujemy;

Dlaczego cyfra u Ciebie jest charem?
Formatujesz kod, ranodmem() z delpi?

Czy Ty chcesz napisać kalkulator dla dwóch bardzo dużych liczb?
Jeżeli tak, to dlaczego nie wczytasz ich do std::string jak człowiek?

0
kopernik napisał(a)

ok,ok.. Jak brzmi zadanie? Po co Ci dwie listy? Co jest w pierwszej a co w drugiej?
Skoro nie umiesz programować, to po co pchasz coś na siłę?Co chciałeś tu osiągnąć?

char (*lista1)()=wczytujemy;

Dlaczego cyfra u Ciebie jest charem?
Formatujesz kod, ranodmem() z delpi?

Zadanie brzmi stworzyć kalkulator który nie będzie ograniczony zakresem zmiennych. Czyli stworzyć typ zmiennych które są ograniczone jedynie pamięcią i wykonywać na nich operacje dodawania mnożenia dzielenia i odejmowania. Czyli ogólnie mamy stworzyć 2 listy(a,b) i poszczególnymi elementami a,b żonglować dodając je,odejmując,mnożąc bądź też dzieląc.
A à propos typu char, bo inaczej nie będzie mi liczby odpowiednio wczytywał z getchar()'a...?
Niczym nie formatuję kodu, po prostu to są kopiuj wkleje różniaste, wszystko pochodzi z Visuala.
A wracając do tematu mam problem z tymi listami, przede wszystkim jak poszczególne elementy listy dodawać. Bo wywala mi błąd handlerowy coś tam coś tam...

0

Ok, więc kod do wywalenia.
Zmienne wczytujesz do stringa.

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int StringToInt(char n){
    return n-'0';
}
string IntToStr(int tmp){
    ostringstream out;
    out<<tmp;
    return out.str();
}
int main(){
    string liczba;
    cin>>liczba;
    int s=0;
    for(int i=0;i<liczba.size();i++){
        s+=StringToInt(liczba[i]);
    }
    cout<<s;
    return 0;
}

fragmenty łancucha zamieniasz na cyferki za pomocą atoi() z cstdlib bądź -'0' jak zrobiłem wyżej.
Cyferki na łańcuch zamieniasz za pomocą IntToStr();
A dalej tak jak "pod kreskę"

0
kopernik napisał(a)

Ok, więc kod do wywalenia.
Zmienne wczytujesz do stringa.

#include <iostream>
#include <string>
#include <sstream>
using namespace std;
int StringToInt(char n){
    return n-'0';
}
string IntToStr(int tmp){
    ostringstream out;
    out<<tmp;
    return out.str();
}
int main(){
    string liczba;
    cin>>liczba;
    int s=0;
    for(int i=0;i<liczba.size();i++){
        s+=StringToInt(liczba[i]);
    }
    cout<<s;
    return 0;
}

fragmenty łancucha zamieniasz na cyferki za pomocą atoi() z cstdlib bądź -'0' jak zrobiłem wyżej.
Cyferki na łańcuch zamieniasz za pomocą IntToStr();
A dalej tak jak "pod kreskę"

Nie wiem jak to mam poprawnie zaimplementowac... -,-' Jakaś porada :D?

0

hmm.. To co Ci dałem to przykład jak używać tej funkcji StrToInt(). a w zmiennej s masz sume wszystkich cyfr wczytanej zmiennej.. Ta zmienna nie będzie Ci do niczego potrzebna, po prostu chciałem Ci pokazać, że można operować na każdej cyferce z osobna, gdy wszystko jest w stringu.
Wczytujesz do dwóch stringów liczby, tak długie jak zechcesz.. Później dodajesz je tak jak na kartce papieru, dodajesz pod kreskę, a wynik zapisujesz w trzecim stringu za pomocą funkcji IntToStr();
Ogólnie użycie do tego listy, to przerost formy nad treścią.. albo głupota..
Możesz też szukać w google jako "C++ własna arytmetyka", ale kod jest na prawdę banalny do implementacji.

0

for(int i=0;i<liczba.size();i++){
s+=StringToInt(liczba[i]);

hm. i w każdym przebiegu tworzysz nowego ostringstreama.
a może by

ostringstream out;
for(int i=0;i<liczba.size();i++)
        out << liczba[i];
cout << out.str();
0

racja.. na szybko naklepałem funkcje do zamiany.. Chociaż właściwie nawet nie trzeba tworzyć ostringstream.

char IntToStr(int tmp){
    return tmp + '0';
}
0

Proste dodawanie możesz zrobić tak:

#include <iostream>
#include <algorithm>
#include <string>
int StrToInt(char n){
    return n-'0';
}
char IntToStr(int n){
    return n+'0';
}
char Plus(char l,char l1,int &p){
    int s=StrToInt(l)+StrToInt(l1)+p;
    p=0;
    if(s<=9)
        return IntToStr(s);
    else{
        p = s/10;
        return IntToStr((s%10));
    }
}
std::string Plus(std::string liczba,std::string liczba1){
    std::string suma;
    int p=0,pozL=liczba.size(),pozR=liczba1.size();
    while(pozL&&pozR){
        suma+=Plus(liczba[pozL-1],liczba1[pozR-1],p);
        pozL--;
        pozR--;
    }
    while(pozL){
        suma+=Plus(liczba[pozL-1],'0',p);
        pozL--;
    }
    while(pozR){
        suma+=Plus(liczba1[pozR-1],'0',p);
        pozR--;
    }
    if(p)
        suma+=IntToStr(p);
    std::reverse(suma.begin(),suma.end());
    return suma;
}
int main(){
    std::string liczba,liczba1;
    std::cin>>liczba;
    std::cin>>liczba1;
    std::cout<<Plus(liczba,liczba1);
    return 0;
}

I na tej podstawie właściwie możesz zrobić resztę działań.

0
kopernik napisał(a)


string Plus(string liczba,string liczba1){
    string suma;
    int p=0,pozL=liczba.size(),pozR=liczba1.size();
    while(pozL&&pozR){
        suma+=Plus(liczba[pozL-1],liczba1[pozR-1],p);
        pozL--;
        pozR--;
    }
    while(pozL){
        suma+=Plus(liczba[pozL-1],'0',p);
        pozL--;
    }
    while(pozR){
        suma+=Plus(liczba1[pozR-1],'0',p);
        pozR--;
    }
    if(p)
        suma+=IntToStr(p);
    reverse(suma.begin(),suma.end());
    return suma;
}


Możesz wytłumaczyć co robi tak funkcja?!

1
string Plus(string liczba,string liczba1){
    string suma;//łańcuch tekstowy do trzymania sumy
    int p=0,pozL=liczba.size(),pozR=liczba1.size();//długości łańcuchów, oraz przeniesienie
    while(pozL&&pozR){//dopóki jets coś w jednym i drugim łańcuchu
//do sumy dodajemy kolejne cyferki zwrócone z funkcji suma, oraz zapisujemy przeniesienie
        suma+=Plus(liczba[pozL-1],liczba1[pozR-1],p);
        pozL--;//jedziemy kolejną pozycje łańcucha
        pozR--;
    }
//jeżeli zostało się coś w pierwszym łańcuchu, to automatycznie oznacza, że nie zostało się nic w drugim(i odwrotnie). Jedziemy do końca
    while(pozL){
        suma+=Plus(liczba[pozL-1],'0',p);//i dodajemy to co się zostało do sumy.
        pozL--;
    }
    while(pozR){//To samo w drugim łańcuchu..
        suma+=Plus(liczba1[pozR-1],'0',p);
        pozR--;
    }
    if(p)//dodajemy ewentualne przeniesienie, które się zostało.
        suma+=IntToStr(p);
    reverse(suma.begin(),suma.end());//na końcu pozostaje odwrócić nam łańcuch
    return suma;
}

Ogólnie mówiąc metoda jak przy dodawaniu pod kreskę. Zaczynamy od końca, dodajemy liczby na tej samej pozycji jeżeli ta suma jest mniejsza od 9, to najzwyczajniej dodajemy ją do łańcucha. W przeciwnym wypadku zostaje nam jeszcze przeniesienie, które należy dodać do sumy cyfr na następnej pozycji.
Gdy skończy się nam jedna z liczb, pozostaje nam dodać do sumy pozostałości z drugiego łańcucha, pamiętając o ewentualnym przeniesieniu.

0

dziękuję...
choć mnożenie może być ciekawe...bo mnoże jedną liczbę z drugą i jedna jest stała a w drugiej zmieniam tylko lokalizacje.
tylko nie wiem..jak zapisuje jedno mnożenie np. 58625..i mnoże 5586 i zapisuje wynik w 3 liczbie string to gdzie zapisywać kolejne liczby (wychodzące z mnożenia 2*586)które później trzeba dodać.? W kolejnym stringu? tylko co jeśli będę mnożyć większe liczby?

0

Możesz dodawać sobie kolejne sumy do vectora<string>, a przesunięcie uzupełniasz zerami. Później dodajesz wszystko funkcją którą napisałem.
Na początku napisz sobie odejmowanie. Jak się wprawisz, to weź się za mnożenie. A najtrudniejsze czyli dzielenie zostaw sobie na koniec.

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