rendered paste body#include <iostream>#include <fstream>#include <string>#include <vector>#include <cmath>using namespace std;const string OLETUS_TIEDOSTO = "yhtalot.txt";const string KYSY_TIEDOSTO = "Anna asetustiedoston nimi (oletuksena "+OLETUS_TIEDOSTO+"): ";const string KYSY_DERIVOI = "Derivoidaanko? (k/e) ";// tietue piirtoalueen tietojen tallentamista vartenstruct piirtoalue { char tm; // taustamerkki int leveys, korkeus; int alkux, alkuy; // x ja y akselin alkuarvot vector<string> merkit;};// tietue termien tallentamista vartenstruct termi { double kerroin, potenssi;};int pyorista(double tulos){ if (tulos < 0) return static_cast<int>(tulos-0.5); else return static_cast<int>(tulos+0.5);}// kysyy käyttäjältä käytettävän tiedoston nimenstring kysyTiedosto(){ string tiedosto = ""; cout << KYSY_TIEDOSTO; getline(cin, tiedosto); if (tiedosto == "") tiedosto = OLETUS_TIEDOSTO; return tiedosto;}// kysyy haluaako käyttäjä derivoida, palauttaa true// arvon jos käyttäjä vastaan k, false jos käyttäjä// vastaa e, muussa tapauksessa kysyy uudestaanbool kysyDerivoi(){ string derivointi; for (;;) { cout << KYSY_DERIVOI; getline(cin, derivointi); if (derivointi == "k") return true; else if (derivointi == "e") return false; }}// lue piirtoalueen tiedot tiedostostapiirtoalue luePiirtoalue(ifstream &tsisaan){ // luo uusi piirtoalue tietue piirtoalue piirto; piirto.tm = tsisaan.get(); tsisaan >> piirto.leveys >> piirto.korkeus; // kasvata merkit rakenne vastaamaan alueen kokoa for (int i = 0; i < piirto.korkeus; ++i) piirto.merkit.push_back(string(piirto.leveys, piirto.tm)); piirto.alkux = -(piirto.leveys / 2); piirto.alkuy = piirto.korkeus / 2; // piirrä koordinaatisto akselit for (int i = 0; i < piirto.korkeus; ++i) for (int j = 0; j < piirto.leveys; ++j) { if (piirto.alkux + j == 0 && piirto.alkuy - i == 0) piirto.merkit.at(i).at(j) = '+'; else if (piirto.alkux + j == 0) piirto.merkit.at(i).at(j) = '|'; else if (piirto.alkuy - i == 0) piirto.merkit.at(i).at(j) = '-'; } return piirto;}// derivoi merkkien määrittämä yhtälö ja kirjoita se tderivaatat virtaan.// oletus, että vakiotermi on viimeisenä.void derivoi(vector<termi> &termit, const string &merkit, ofstream &tderivaatat){ for (int i = 0; i < termit.size(); ++i) { // jos termin potenssi on 0 on kyseessä vakiotermi ja se poistetaan if (static_cast<int>(termit.at(i).potenssi) == 0) { termit.erase(termit.begin()+i); break; } // laske termien uusi arvo termit.at(i).kerroin = termit.at(i).kerroin * termit.at(i).potenssi; termit.at(i).potenssi = termit.at(i).potenssi - 1; } // kirjoita käytettävät merkit ja termien uusi lukumäärä tderivaatat << merkit << " " << termit.size(); for (int i = 0; i < termit.size(); ++i) tderivaatat << " " << termit.at(i).kerroin << " " << termit.at(i).potenssi; tderivaatat << endl;}// piirrä termien määrittelemä yhtälö käyttäen merkit merkkijonon merkkejävoid piirra(piirtoalue &piirto, const vector<termi> &termit, const string &merkit){ // monesMerkki on indeksi merkit merkkijonoon, jota käytetään pitämään kirjaa kulloinkin tulostettavasta merkistä. unsigned int monesMerkki = 0; for (int x = piirto.alkux; x < piirto.alkux + piirto.leveys; ++x) { double tulos = 0; for (int i = 0; i < termit.size(); ++i) tulos += termit.at(i).kerroin * pow(x, termit.at(i).potenssi); int y = piirto.alkuy - pyorista(tulos); if (y >= 0 && y < piirto.korkeus) piirto.merkit.at(y).at(x - piirto.alkux) = merkit[monesMerkki]; if (++monesMerkki == merkit.length()) monesMerkki = 0; }}void tulosta(piirtoalue &piirto){ // rivi ja sarake piirtävät x- ja y-akselin numerot. Haluttu numero saa- // daan jakamalla oikea arvo kymmenellä ja ottamalla siitä jakojäännös. cout << endl; for (int i = 0; i < piirto.korkeus; ++i) { int rivi = piirto.alkuy - i; if ( rivi < 0 ) rivi = -rivi % 10; else rivi = rivi % 10; // tulosta nykyinen rivi cout << rivi << piirto.merkit.at(i) << endl; } cout << " "; for (int i = 0; i < piirto.leveys; ++i) { int sarake = piirto.alkux + i; if (sarake < 0) sarake = -sarake % 10; else sarake = sarake % 10; cout << sarake; } cout << endl;}int main(){ cout << "### OHJ-1101 Ohjelmointi Ie - Harjoitustyö - kako" << endl; cout << "### Henri Lipsanen, lipsaneh" << endl; cout << "### 199051, Tietojohtaminen" << endl; // kysy käyttäjältä käytettävä tiedosto ja avaa se tsisaan virtana // tai tulosta virhe ja poistu ohjelmasta jos tiedostoa ei voitu avata. string tiedosto = kysyTiedosto(); ifstream tsisaan(tiedosto.c_str()); if ( !tsisaan ) { cout << "Virhe: Tiedostoa " << tiedosto << " ei voida lukea." << endl; return EXIT_FAILURE; } // kysy haluaako käyttäjä derivoida. bool derivointi = kysyDerivoi(); // luo uusi piirtoalue tiedostossa olevien tietojen mukaan. piirtoalue piirto = luePiirtoalue(tsisaan); ofstream tderivaatat; if (derivointi) { tderivaatat.open((tiedosto + ".derivaatat").c_str()); tderivaatat << piirto.tm << " " << piirto.leveys << " " << piirto.korkeus << endl; } // jatka niin kauan kuin tiedostosta pystyy lukemaan while (tsisaan) { string merkit; tsisaan >> merkit; if (!tsisaan) break; vector<termi> termit; int termeja, i = 0; tsisaan >> termeja; // lue tarvittavat termit tiedostosta for (i = 0; i < termeja; ++i) { termi tmp; tsisaan >> tmp.kerroin >> tmp.potenssi; termit.push_back(tmp); } if (derivointi) derivoi(termit, merkit, tderivaatat); piirra(piirto, termit, merkit); } tulosta(piirto); return EXIT_SUCCESS;}