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;
}
// -------------------------------------------------------
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.
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! :)
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;
}
}
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.
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 :)
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!