7 svar
136 visningar
shiela är nöjd med hjälpen!
shiela 27
Postad: 18 aug 2020

Värdet på histogram_rel är 0 när den skickas in och ut ur abs_till_rel, det ska den ej vara!

Hej!

Kan någon hjälpa mig förstå varför arrayen histogram_rel är 0 när den skickas IN OCH när den skickas UT ur funktionen abs_till_rel()?

Den ska inte vara 0. Det leder till att när jag senare kallar på funktionen plotta_histogram_rel() med histogram_rel så blir histogrammet 0 eftersom histogram_rel är 0. 

 

Tack på förhand!


//

// Programskal till obluppg5A

//

// Hanterar fallet med 26 bokst‰ver A-Z

 


#include <string>

#include <cctype>

#include <iostream>

#include <fstream>

#include <cmath>

using namespace std;

 


// Globala konstanter:

 


const int ANTAL_BOKSTAVER = 26;  //A-Z

const int ANTAL_SPRAK = 4;

 

const double TOLK_HJALP[ANTAL_SPRAK][ANTAL_BOKSTAVER]=

       {{8.27,1.48,2.94,4.03,11.78,2.22,1.72,6.77, //engelska

         7.39,0.12,0.81,3.76,2.85,6.71,7.79,1.54,

         0.05,5.95,6.69,9.07,2.66,1.13,2.14,0.19,

         1.89,0.03},

        {7.97,1.40,3.55,3.79,16.89,1.02,1.00,0.75, //franska

         7.08,0.38,0.04,5.51,2.82,8.11,5.19,2.78,

         1.01,6.69,8.35,7.22,6.09,1.35,0.02,0.54,

         0.30,0.15},

        {9.50,1.11,1.53,5.30,8.94,1.74,3.57,3.94,  //svenska

         3.98,0.89,3.26,4.93,3.41,8.46,5.01,1.77,

         0.00,6.73,5.56,9.20,1.94,2.42,0.00,0.05,

         0.45,0.00},

        {5.12,1.95,3.57,5.07,16.87,1.35,3.00,5.79, //tyska

         8.63,0.19,1.14,3.68,3.12,10.64,1.74,0.42,

         0.01,6.30,6.99,5.19,3.92,0.77,1.79,0.01,

         0.69,1.24}};

 


// Globala variabler ‰r ej tillÂtna

 


//--------------------------------------------------------

// Klassdeklarationen

class Text

{

private:                                            //Attribut

    string textUt;                                   //Textsträng för analys

    int histogram_abs[ANTAL_BOKSTAVER] = {0};           //Array, innehåller absoluta histogrammet, längen är 26

    double histogram_rel[ANTAL_BOKSTAVER] = {0.0};     //Array, innehåller relativa histogrmmet

    int antal;                                          //Attribut som håller reda på antal bokstäver i histogrammet

 


    

public:                                 //Metoder

    Text();                             //Standardkonstruktor

    

 


    void set_text(string ny_text);      //Metod (funktion) som sätter värdet på textsträngen i klassen

    

    bool berakna_histogram_abs(const string& textUt, int(&frekvens)[ANTAL_BOKSTAVER]);

    

    void skriv_histogram_abs(const int(&frekvens)[ANTAL_BOKSTAVER]);     //Skriver ut bokstavshistogrammet

    

    void abs_till_rel(const std::string& textUt, int(&histogram_abs)[ANTAL_BOKSTAVER], double(&histogram_rel)[ANTAL_BOKSTAVER]);   //Metod som beräknar relativt histogram

    

    void plotta_histogram_rel(const double(&histogram_rel)[ANTAL_BOKSTAVER]); //Metod som plottar relativa histogrammet

    

    void berakna_histogram(const std::string& textUt, int(&histogram_abs)[ANTAL_BOKSTAVER], double(&histogram_rel)[ANTAL_BOKSTAVER]);           //Gör inga nya beräkningar av histogrammet, men ska anropa berakna_histogram_abs() och abs_till_rel(). Det absoluta beräknas först och sedan det relativa histogrammet. Det relativa histogrammet ska bara beräknas om det absoluta histogrammet innehåller bokstäver.

    

    void tolka(const double(&histogram_rel)[ANTAL_BOKSTAVER]);     //Metoden jämför beräknat relativt histogram med fyra fördefinerade språkhistogram

};

 


    string namn_pa_fil(string namn);

    string inlasning(const string& namn);

    string snyggaTillText(string text);

// -------------------------------------------------------

 


// Huvudprogram:

 


int main()

{

 // Deklarera variabler

  string text;

  string textUt;                                //Textsträng för analys

  int histogram_abs[ANTAL_BOKSTAVER] = {0};     //Array, innehåller absoluta histogrammet, längen är 26

  double histogram_rel[ANTAL_BOKSTAVER] = {0.0};     //Array, innehåller relativa histogrmmet'

  string filnamn;

    

  bool hist_OK;

  Text min_text;                            // Ett objekt av typen Text skapas

 


  filnamn = namn_pa_fil(filnamn);

  text = inlasning(filnamn);

  textUt = snyggaTillText(text);

    

  min_text.set_text(textUt);          //Skickar strängen 'textUt' till objektet, ger text storleken 64 minText

    

  // Ber‰kna och skriv ut histogrammet

  //hist_OK = min_text.berakna_histogram_abs(textUt, histogram_abs);

  //min_text.abs_till_rel(textUt, histogram_abs, histogram_rel);

 


  min_text.berakna_histogram(textUt, histogram_abs, histogram_rel);

  min_text.skriv_histogram_abs(histogram_abs);

  min_text.plotta_histogram_rel(histogram_rel);

  min_text.tolka(histogram_rel);

  return 0;

}

 


// -------------------------------------------------------

// Klassimplementationen

 


Text::Text()                          //Skapar och nollställer standardkonstruktorn

{

   textUt="";


   for(int i=0; i<ANTAL_BOKSTAVER; i++)

   {

       histogram_abs[i]=0;

   }

   antal=0;

}

 


void Text::set_text(string ny_text)           //Tilldelar variabeln text ett värde

{

   textUt = ny_text;

}


bool Text::berakna_histogram_abs(const string& textUt, int(&frekvens)[ANTAL_BOKSTAVER])            //Beräknar förekomst av olika bokstäver

{

   for (int i=0; i<ANTAL_BOKSTAVER; i++)

   {

       histogram_abs[i] = 0;                 //Nollställer frekvensen

   }

   antal=0;


   for(unsigned int i = 0; i<textUt.length(); i++)

   {

       char temp = textUt[i];

           if(isalpha(temp))               //Om tecknet är en bokstav så vill vi öka med 1

           antal++;


           if(isupper(textUt[i]))            //Om bokstaven är en stor bokstav så ändras den till en liten

           temp=tolower(temp);

           histogram_abs[(temp - 'a')]++;   // frekvensräknaren för den valda bokstaven ökas med 1

   }

   if(antal==0)                            //Om antalet bokstäver är noll så ges boolen värdet false, annars är den true

       return false;

   else

       return true;

}

 

 

 

 

void Text::skriv_histogram_abs(const int(&frekvens)[ANTAL_BOKSTAVER])

{

    cout << "\nResultat för bokstäverna A-Z " << endl;

    cout << "\nTotala tecken i texten: " << textUt.size() << endl;

    cout <<"\nBokstav:\tFrekvens:\n";


   for (int i=0; i<ANTAL_BOKSTAVER; i++)

   {

       char Bokstav = char (i+'A');

       if (histogram_abs[i])

           cout << Bokstav << "        \t" << histogram_abs[i] <<endl;

       else

           cout << Bokstav << "               0" << endl;

       

   }

   

}


void Text::abs_till_rel(const std::string& textUt, int(&histogram_abs)[ANTAL_BOKSTAVER], double(&histogram_rel)[ANTAL_BOKSTAVER]) //Denna funktion ska omvandla absoluta (stycken) fˆrekomsten av varje bokstav till en relativ (andel i %) fˆrekomst av varje bokstav

{

    int antal = textUt.size();

    cout <<"Detta är vad histogram_rel är när den skickas in i abs_till_rel(DENNA SKA EJ VARA 0):" << histogram_rel[ANTAL_BOKSTAVER] << endl;

    for (int i = 0; i < ANTAL_BOKSTAVER; i++)

    {

        histogram_rel[i] = float((double)histogram_abs[i] / float(antal)) * 100.0;

        cout << "Detta är vad histogram_rel är när den skickas UT ur abs_till_rel(DENNA SKA EJ VARA 0):" << histogram_rel[i] << endl;

    }

}

 

void Text::plotta_histogram_rel(const double(&histogram_rel)[ANTAL_BOKSTAVER]) //Denna funktion ska nu plotta den relativa fˆrekomsten av varje bokstav

{

    char bokstav;

    cout << "\nBokstav:\tRelativ frekvens:\n";

    cout << "Vad är histogram_rel i plotta_histogram_rel för relativa histogrammet!!" << histogram_rel[ANTAL_BOKSTAVER] << endl;

    for (int i = 0; i < ANTAL_BOKSTAVER; i++)

    {

        double k = 0.5;

        bokstav = 'A' + i;

        cout << bokstav << ": ";

        cout << "Vad är histogram_rel innan loop för relativa histogrammet!!" << histogram_rel[i] << endl;

        while (k < histogram_rel[i])

        {

            cout << "*";

            k += 0.5;

        }

        cout << "Nu vill vi se histogram_rel i relativa histogrammet!!" << histogram_rel[i] << endl;

        cout << endl;

    }

}

 

 

//Gör inga nya beräkningar av histogrammet, men ska anropa berakna_histogram_abs() och abs_till_rel(). Det absoluta beräknas först och sedan det relativa histogrammet. Det relativa histogrammet ska bara beräknas om det absoluta histogrammet innehåller bokstäver.

void Text::berakna_histogram(const std::string& textUt, int(&histogram_abs)[ANTAL_BOKSTAVER], double(&histogram_rel)[ANTAL_BOKSTAVER])

{

   bool histOK=Text::berakna_histogram_abs(textUt, histogram_abs);

        cout << "Detta är vad histogram_rel är inne i berakna_histogram:" << histogram_rel[ANTAL_BOKSTAVER] << endl;

   if (histOK)

   {

       Text::abs_till_rel(textUt, histogram_abs, histogram_rel);

   }

   else

       cout << "Texten innehåller inga bokstäver.";

}

 

void Text::tolka(const double(&histogram_rel)[ANTAL_BOKSTAVER])

{

    double minsta_skillnaden;          //Minsta skillnaden mellan frekvenser i texten och sprÂken

    int minsta_index;                //Index fˆr det sprÂk med minsta skillnaden

    string sprak[ANTAL_SPRAK] = { "engelska", "franska", "svenska", "tyska" };

    double skillnad = 0.0;             //Skillnaden mellan frekvens i texten och frekvens i sprÂken

    double summa[ANTAL_SPRAK] = { 0.0, 0.0, 0.0, 0.0 };     //Summan av kvadraterna av de olika skillnaderna


    for (int j = 0; j < ANTAL_SPRAK; j++)

    {

        for (int i = 0; i < ANTAL_BOKSTAVER; i++)

        {

            skillnad = (TOLK_HJALP[j][i] - histogram_rel[i]);    //Ber‰knar skillnad i frekvens fˆr varje bokstav i texten och sprÂken

            summa[j] = summa[j] + (skillnad * skillnad);    //Summerar kvadraterna av skillnader i frekvens

        }

        minsta_skillnaden = summa[j];                      //Startgissning

        minsta_index = j;                                //Startgissning

 


        for (int k = 0; k < ANTAL_SPRAK; k++)

        {

            if (summa[k] < minsta_skillnaden)          //Kontroll om summan ‰r mindre ‰n minsta skillnaden

            {

                minsta_skillnaden = summa[k];              //Uppdaterar den nya minsta skillnaden

                minsta_index = k;                        //Uppdaterar index fˆr det sprÂk med minst skillnad

            }

        }

    }

    cout << "Engelska har kvadratsumman: " << summa[0] << endl;

    cout << "Franska har kvadratsumman: " << summa[1] << endl;

    cout << "Svenska har kvadratsumman: " << summa[2] << endl;

    cout << "Tyska har kvadratsumman: " << summa[3] << endl;

    

    cout << "Det är mest troligt att språket är: " << sprak[minsta_index] << endl;

}

 


//--------------------------------------------------------

// Funktionsdefinitioner:

 


string namn_pa_fil(string filnamn)

{

    cout << "Vad heter filen du vill testa?: " << endl;

    getline(cin, filnamn);

 


    if (filnamn.rfind(".txt") == string::npos)

    {

        filnamn.append(".txt");

    }

    return filnamn;

}

 

string inlasning(const string& filnamn)

{

    string tmpString;

    string returneradText;

    ifstream fin(filnamn.c_str());

    if (!fin)

    {

        cout << "Det finns ingen fil med namnnet " << filnamn << endl;

        exit(EXIT_FAILURE);

    }

    else

    {

        while (getline(fin, tmpString))

        {

            returneradText += tmpString;

        }

    }

    

    return returneradText;

}

 


string snyggaTillText(string text)

{

    string::iterator c(text.begin());

    

    while (c != text.end())

    {

        if  ((*c < 'A' || *c > 'Z') && (*c < 'a' || *c > 'z'))

        {

            c = text.erase(c);

        }

        else

        {

            c++;

        }

    }

 


    return text;

}

// -------------------------------------------------------

Laguna 11665
Postad: 18 aug 2020

Att skriva ut histogram_rel[ANTAL_BOKSTAVER] är inte meningsfullt, för det är utanför vektorn. histogram_rel[ANTAL_BOKSTAVER-1] är sista elementet.

Skriv ut histogram_abs[i] i loopen också, så vi vet att den inte är noll. 

shiela 27
Postad: 18 aug 2020
Laguna skrev:

Att skriva ut histogram_rel[ANTAL_BOKSTAVER] är inte meningsfullt, för det är utanför vektorn. histogram_rel[ANTAL_BOKSTAVER-1] är sista elementet.

Skriv ut histogram_abs[i] i loopen också, så vi vet att den inte är noll. 

Tack, jag kollade faktiskt den också, den är inte 0! :)

shiela 27
Postad: 18 aug 2020 Redigerad: 18 aug 2020
Laguna skrev:

Att skriva ut histogram_rel[ANTAL_BOKSTAVER] är inte meningsfullt, för det är utanför vektorn. histogram_rel[ANTAL_BOKSTAVER-1] är sista elementet.

Skriv ut histogram_abs[i] i loopen också, så vi vet att den inte är noll. 

Ledsen Laguna, jag tro jag missförstod vad du menade!
Ja precis, när jag skrev ut histogram_abs[i] i loopen som finns i funktionen abs_till_rel() och den är också 0!

Var det det du menade?  Se nedan:

 

void Text::abs_till_rel(const std::string& textUt, int(&histogram_abs)[ANTAL_BOKSTAVER], double(&histogram_rel)[ANTAL_BOKSTAVER]) //Denna funktion ska omvandla absoluta (stycken) fˆrekomsten av varje bokstav till en relativ (andel i %) fˆrekomst av varje bokstav

{

    int antal = textUt.size();

    for (int i = 0; i < ANTAL_BOKSTAVER; i++)

    {

        histogram_rel[i] = float((double)histogram_abs[i] / float(antal)) * 100.0;

        cout << "Detta är vad histogram_rel är när den skickas UT ur abs_till_rel(DENNA SKA EJ VARA 0):" << histogram_rel[i] << endl;

        cout << "Detta är vad histogram_abs är när den skickas UT ur abs_till_rel (SKA INTE HELLER VARA 0):" << histogram_abs[i] << endl;

    }

}

Laguna 11665
Postad: 18 aug 2020

Ja, men nu har jag hittat felet, och det var inte helt lätt: du har två vektorer som heter histogram_abs, en i main och en i klassen. berakna_histogram_abs ändrar inte i den du tror, för du har kallat parametern 'frekvens' där, men ändrar i histogram_abs.

Ta bort den ena av dem, och red ut de fel som sen uppstår. Jag är inte säker på vilken som det är bäst att ta bort - det spelar nog ingen roll.

Kompilatorn kan tipsa om detta fel, om man säger åt den att ge maximal mängd varningar. Med g++ skriver man -Wall -Wextra, och då säger den att 'frekvens' inte används. Ta reda på om din kompilator kan ge varningar.

Laguna skrev:

Ja, men nu har jag hittat felet, och det var inte helt lätt: du har två vektorer som heter histogram_abs, en i main och en i klassen. berakna_histogram_abs ändrar inte i den du tror, för du har kallat parametern 'frekvens' där, men ändrar i histogram_abs.

Ta bort den ena av dem, och red ut de fel som sen uppstår. Jag är inte säker på vilken som det är bäst att ta bort - det spelar nog ingen roll.

Kompilatorn kan tipsa om detta fel, om man säger åt den att ge maximal mängd varningar. Med g++ skriver man -Wall -Wextra, och då säger den att 'frekvens' inte används. Ta reda på om din kompilator kan ge varningar.

Bra felsökning av Laguna. Jag rekommenderar starkt att ta bort histogram_abs från main. Då kan du nyttja mer av fördelarna med inkapslingen av histogram_abs i klassen. Objektet my_text har du ju redan.

shiela 27
Postad: 19 aug 2020
Laguna skrev:

Ja, men nu har jag hittat felet, och det var inte helt lätt: du har två vektorer som heter histogram_abs, en i main och en i klassen. berakna_histogram_abs ändrar inte i den du tror, för du har kallat parametern 'frekvens' där, men ändrar i histogram_abs.

Ta bort den ena av dem, och red ut de fel som sen uppstår. Jag är inte säker på vilken som det är bäst att ta bort - det spelar nog ingen roll.

Kompilatorn kan tipsa om detta fel, om man säger åt den att ge maximal mängd varningar. Med g++ skriver man -Wall -Wextra, och då säger den att 'frekvens' inte används. Ta reda på om din kompilator kan ge varningar.

Tack Laguna, för att du hittade detta fel och tog dig tiden att sätta dig in i problemet! Hade aldrig hittat felet själv.

Det tog lång tid att fixa, men nu funkar det :) 

shiela 27
Postad: 19 aug 2020
Lindehaven skrev:
Laguna skrev:

Ja, men nu har jag hittat felet, och det var inte helt lätt: du har två vektorer som heter histogram_abs, en i main och en i klassen. berakna_histogram_abs ändrar inte i den du tror, för du har kallat parametern 'frekvens' där, men ändrar i histogram_abs.

Ta bort den ena av dem, och red ut de fel som sen uppstår. Jag är inte säker på vilken som det är bäst att ta bort - det spelar nog ingen roll.

Kompilatorn kan tipsa om detta fel, om man säger åt den att ge maximal mängd varningar. Med g++ skriver man -Wall -Wextra, och då säger den att 'frekvens' inte används. Ta reda på om din kompilator kan ge varningar.

Bra felsökning av Laguna. Jag rekommenderar starkt att ta bort histogram_abs från main. Då kan du nyttja mer av fördelarna med inkapslingen av histogram_abs i klassen. Objektet my_text har du ju redan.

Tack så mycket för din kommentar Lindehaven! 

Svara Avbryt
Close