Just nu i M3-nätverket
Gå till innehåll

Problem att få en metod i en klass att fungera


BEAESK

Rekommendera Poster

Hej

Jag hört kört fast på en programmeringsuppgift som ska vara inlämna imorgon sad44.gif

Den går ut på att jag ska skriva ett program som läser in en textfil och sedan beräknar förekomsten av bokstäverna A-Z och jämför resultatet med fyra olika språks bokstavsfrekvenser. Programmet ska alltså kunna användas till att avgöra vilket språk en text är skriven på.

Först ska den absoluta förekomsten beräknas och utifrån det den procentuella förekomsten. De metoder som finns med är de vi ska använda oss av. Jag har kört fast på metoden absTillRel där resultatet blir noll för alla bokstäver. Beräkningen av den absoluta förekomsten fungerar finfint. Alla delar i huvudprogrammet är inte med ännu.

Vore hemskt tacksam om någon kan hjälpa mig.

 

#include <string>
#include <cctype>
#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdlib>
using namespace std;

const int ANTAL_BOKSTAVER = 26;  //A-Z
const int ANTAL_SPRAK = 4;

// 2d-arrayen TOLK_HJALP innehåller bokstavsfrekvensen i %
// för fyra språk. TOLK_HJALP[0][0] är frekvensen av
// bokstaven a för engelska.TOLK_HJALP[0][25] är frekvensen av
// bokstaven z för engelska.
// Arrayen är en GLOBAL KONSTANT och skall alltså ej skickas
// som parameter till den funktion som behöver den.
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}};



//--------------------------------------------------------
class Text
{
private:
   string text;
   int HistogramAbs[ANTAL_BOKSTAVER];
   double HistogramRel[ANTAL_BOKSTAVER];
   int antal;

public:
   Text();                         //Standardkonstruktor
   void setText(string nyText);   //Ger "text" ett värde
   bool beraknaHistogramAbs();     //Beräknar ett bokstavshistogram
   void skrivHistogramAbs();       //Skriver ut bokstavshistogrammet
   void absTillRel();             //Räknar om absolutvärdena till relativa värden
   void plottaHistogramRel();     //Plottar det relativa histogrammet
   void beraknaHistogram();       //Beräknar relativa histogrammet förutsatt att det finns bokstäver i absoluthistogrammet
   string tolka();                //Jämför det relativa histogrammet med språkhistogrammet
};

string namn_pa_fil(string namn);
void inlasning(string &namn, string &text);

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

// Huvudprogram:

int main()
{
// Deklarera variabler
 string text;
 bool histOK;
 Text minText;                             // Ett objekt av typen Text skapas
 string filnamn;
 double HistogramRel;

 filnamn = namn_pa_fil(filnamn);
 inlasning(filnamn, text);
 minText.setText( text );                  //Skicka strängen text till objektet minText
 histOK = minText.beraknaHistogramAbs( );
 minText.absTillRel();
 minText.skrivHistogramAbs( ); 

 return 0;
}

// -------------------------------------------------------
//Klassimplementation

Text::Text()                                //Skapar och nollställer standardkonstruktorn
{
   text="";

   for(int i=0; i<ANTAL_BOKSTAVER; i++)
   {
       HistogramAbs[i]=0;
   }
   for(int i=0;i<ANTAL_BOKSTAVER;i++)
   {
       HistogramRel[i]=0.0;
   }

   antal=0;
}


void Text::setText(string nyText)           //Tilldelar variabeln text ett värde
{
   text = nyText;
}


bool Text::beraknaHistogramAbs()            //Beräknar förekomst av olika bokstäver
{
   for (int i=0; i<ANTAL_BOKSTAVER; i++)
   {
       HistogramAbs[i] = 0;                 //Nollställer frekvensen
   }


   antal=0;
   for(unsigned int i = 0; i<text.length(); i++)
   {
       char temp = text[i];
           if(isalpha(temp))               //Om tecknet är en bokstav
           antal++;                        //ökar räknaren med 1

           if(isupper(text[i]))            //Om bokstaven är en versal så ändras den till en gemen
           temp=tolower(temp);
           HistogramAbs[(temp - 'a')]++;   // frekvensräknaren för den valda bokstaven ökas med 1
   }

   if(antal==0)                            //Om antalet bokstäver är noll
       return false;                       //returneras "false"
   else                                    //annars
       return true;                        //reurneras "true"
}


void Text::skrivHistogramAbs()
{
   cout <<"\nBokstav:\tFrekvens:\n";       //Skriver ut rubriker till histogrammet

   for (int i=0; i<ANTAL_BOKSTAVER; i++)
   {
       char Bokstav = char (i+'A');        //Beräknar tecken utifrån position
       if (HistogramAbs[i])
           cout << Bokstav << "        \t" << HistogramAbs[i] <<endl;  //Skriver ut tecknens frekvens

       else
           cout << Bokstav << "               0" << endl;              //Skriver ut en nolla för de tecken som inte finns med i texten
   }
}


void Text::absTillRel()
{
   for (int i=0; i<ANTAL_BOKSTAVER; i++)
   {
       HistogramRel[i] = (HistogramAbs[i])/(antal)*100;         //Bokstävernas absoluta förekomst divideras med totala antalet
                                                               //tecken för att beräkna den relativa förekomsten
   }
}


void Text::plottaHistogramRel()
{
   cout <<"\nBokstav:\tFrekvens:\n";         //Skriver ut rubriker i histogrammet

   int j;
   for(int i=0; i<ANTAL_BOKSTAVER; i++)
   {
       cout << char('A'+i) << "            "; //Beräknar tecken utifrån position
       j = 2*HistogramRel[i];                 //Dubblar frekvensen så att en * skrivs för var halv procent

           for(int k=0; k<j; k++)
           {
               cout << '*';
           }

               cout << endl;
   }
}

void Text::beraknaHistogram()
{
   bool histOK=Text::beraknaHistogramAbs();
   if (histOK)
   {
       Text::absTillRel();
   }
   else
       cout << "Texten innehåller inga bokstäver.";

}


string Text::tolka()
{
  double minst_skillnad;          //Minsta skillnaden mellan frekvenser i texten och de olika språken
   int minst_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 de olika 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] - HistogramRel[i]);    //Beräknar frekvensskillnad för varje bokstav i texten och de olikaspråken
           summa[j] = summa[j]+(skillnad*skillnad);    //Summerar kvadraterna av frekvensskillnaderna
       }


       minst_skillnad = summa[j];                      //Startgissning
       minst_index = j;                                //Startgissning
       for(int k=0; k<ANTAL_SPRAK; k++ )
       {
           if(summa[k]<minst_skillnad)                 //Om summan är mindre än minsta skillnaden
           {
               minst_skillnad = summa[k];              //Uppdaterar med den nya minsta skillnaden
               minst_index = k;                        //Uppdaterar med index för det språk med minsta skillnaden
           }
       }
   }
   cout << "Texten ar troligen skriven pa: " << sprak[minst_index] << endl;    //Skriver ut vilket språk texten troligen är skriven på
   return 0;
}
//-----------------------------------------------------------
//Funktionsdefinitioner

string namn_pa_fil(string filnamn)                    //Efterfrågar namnet på filen man vill kontrollera
{
cout << "Vad heter filen du vill testa?: " << endl;
getline(cin, filnamn);

   if (filnamn.rfind(".txt") == string::npos)        //Kontrollerar om det angivna filnamnet har rätt format
   {
       filnamn.append(".txt");                       //Lägger till ändelsen .txt ifall det saknas
   }
   return filnamn;
}


void inlasning(string &filnamn, string &text)         //Läser in den valda filen
{
string tmpString;                                  //Skapar en temporär sträng
ifstream fin(filnamn.c_str() );                       //Skapar objektet fin

   if(!fin)                                       //Kontrollerar om den valda filen finns
   {
       cout << "Det finns ingen fil med namnnet " << filnamn << endl;
       exit(EXIT_FAILURE);                        //Avslutar programmet
   }

   else

       while (getline(fin, tmpString))
       {
           for (int i=0; i<=(int) text.length()-1; i++)

               text.at(i);                        //Läser in texten tecen för tecken
               text +=tmpString;                  //Uppdaterar texten för varje tecken
       }
   }

Länk till kommentar
Dela på andra webbplatser

Never mind, jag fick hjäp från annat håll men jag kikar säkert in här igen nästa gång jag kör fast. Hoppas ingen lagt för mycket tid på att kolla genom min kod redan.

Länk till kommentar
Dela på andra webbplatser

Arkiverat

Det här ämnet är nu arkiverat och är stängt för ytterligare svar.

×
×
  • Skapa nytt...