Zápočet 10.2.2014

Základní kurs objektově orientovaného programování v C++. Třídy a objekty, zapouzdření, metody, plymorfismus. Abstraktní datové typy, přetěžování. Kontejnery, iterátory, algoritmy. Šablony, generické programování, kompilační polymorfismus. Výjimky. Bezpečné a přenositelné programování, vazby na OS.
Lazybug123

Zápočet 10.2.2014

Příspěvek od Lazybug123 »

Dnesna zapoctovka bola mimoriadne lahka, mali sme napisat zasobnikovy stroj. Internet bol povoleny, vlastne pocitace nie, alebo len velmi neoficialne. Hotove a otestovane som to mala za hodinu a stvrt. Odchadzala som prva, takze uspesnost netusim.

Zadanie:
Napiste zasobnikovy stroj. Instrukcie sa nacitavaju zo suboru (nazov zadratovany natvrdo), vypisuju na konzolu (ale ja som vypisovala aj do suboru, aby sa to lahsie testovalo). Argumenty su inty. Zly vstup sa neriesil. Zasobnik sa cisluje od nuly. Ma to vediet instrukcie:
ADD - odoberie 2 vrchne polozky, scita, vysledok ulozi na vrch zasobnika
SUB - odoberie 2 vrchne polozky, odcita, vysledok ulozi na vrch zasobnika. Lavy operand je ten, ktory bol hlbsie.
HALT - vypise zasobnik a ukonci program
LD x - na vrch zasobnika prida konstantu
JMP x - skoci o x instrukcii dopredu (napr JMP 1 nerobi nic, JMP 0 spravi nekonecny cyklus). Argument moze byt aj zaporny, v tom pripade skace dozadu.
JP x - odoberie 1 polozku z vrchu zasobnika, ak je kladna, skoci o x instrukcii dopredu
JZ x - odoberie 1 polozku z vrchu zasobnika, ak je rovna nule, skoci o x instrukcii dopredu
ST x - skopiruje vrchol zasobnika a vlozi ho na x-tu poziciu (tym bolo myslene, ze cislo na x-tej pozicii prepise), potom zmaze vrchol zasobnika. Napr. ST 0 zrusi vrchol zasobnika.
DUP x - Polozku na x-tej pozicii skopirujeme a pridame na vrchol zasobnika.


Riesenie:
Velmi priamociare, ziadne zakernosti, len to bolo trochu pracne kvoli poctu instrukcii. Stacilo na zaciatku vybrat spravnu reprezentaciu zasobnika (std::deque<int>) a potom to uz islo. Moje riesenie:

Kód: Vybrat vše

#include <vector>
#include <stack>
#include <deque>
#include <fstream>
#include <iostream>
#include <string>

using namespace std;

class Stroj{
public:
	deque<int> z; //zasobnik
	vector<string> prikazy;
	void Vykonaj(int i);
	int indexPrikazu; //zacina od nuly, index prikazu v prikazy
};

void Stroj::Vykonaj(int x)
{
	string riadok = prikazy[x];
	string prikaz = "";
	int param = 0;
	string paramStr = "";
	int j = 0;

	while (j < riadok.length() && riadok[j] != ' ')
	{
		prikaz += riadok[j];
		j++;
	}

	if (j < riadok.length()) // ak je za prikazom param
	{
		j++;
		while(j < riadok.length())
		{
			paramStr += riadok[j];
			j++;
		}
		param = atoi(paramStr.c_str());
	}
	

	if (prikaz == "ADD")
	{
		int a = z.front();
		z.pop_front();
		int b = z.front();
		z.pop_front();
		z.push_front(a + b);
		indexPrikazu++;
	}
	else if (prikaz == "SUB")
	{
		// levy operand hloubeji
		int a = z.front();
		z.pop_front();
		int b = z.front();
		z.pop_front();
		z.push_front(b-a);
		indexPrikazu++;
	}
	else if (prikaz == "HALT")
	{
		ofstream vystup("vystup.txt");
		while (!z.empty())
		{
			cout << z.front() << endl;
			vystup << z.front() << endl;
			z.pop_front();
		}
		vystup.close();
		exit(0);
	}
	else if (prikaz == "LD")
	{
		z.push_front(param);
		indexPrikazu++;
	}
	else if (prikaz == "JMP")
	{
		indexPrikazu += param;
	}
	else if (prikaz == "JZ")
	{
		int vrch = z.front();
		z.pop_front();

		if (vrch == 0)
			indexPrikazu += param;
		else
			indexPrikazu++;
	}
	else if (prikaz == "JP")
	{
		int vrch = z.front();
		z.pop_front();

		if (vrch > 0)
			indexPrikazu += param;
		else
			indexPrikazu++;
	}
	else if (prikaz == "DUP")
	{
		int a = z[param];
		z.push_front(a);

		indexPrikazu++;
	}
	else if (prikaz == "ST")
	{
		int vrch = z.front();

		if (param == z.size()) //ak musime vytvorit novy prvok
			z.push_back(vrch);
		else
			z[param] = vrch;

		z.pop_front();

		indexPrikazu++;
	}
	else
	{
		cout << "CHYBNY PRIKAZ, pokracujem dalsim";
		indexPrikazu++;
	}

}

int main(int argc, const char* argv[])
{
	Stroj p;
	
	//nacitaj
	ifstream vstup("vstup.txt");
	string riadok;
	while (getline(vstup, riadok))
	{
		p.prikazy.push_back(riadok);
	}
	vstup.close();

	//vykonaj
	p.indexPrikazu = 0;
	while (p.indexPrikazu < p.prikazy.size())
	{
		p.Vykonaj(p.indexPrikazu);
	}

	return 0;
}

Testovalo sa to na tomto vstupe, vraj to pocitalo Fibonacciho cisla, malo to vypisat cislo 89.

Kód: Vybrat vše

LD 10
LD 0
LD 1
DUP 1
DUP 1
ST 3
ADD
DUP 2
LD 1
SUB
DUP 0
ST 4
JP -9
ST 2
ST 0
HALT
Odpovědět

Zpět na „NPRG041 Programování v C++“