4 svar
919 visningar
shiela behöver inte mer hjälp
shiela 23 – Fd. Medlem
Postad: 17 aug 2020 18:43

Hjälp med att räkna ut kvadratsumma korrekt

Hej, 

Jag måste ändra i denna kod eftersom kvadratsumman som beräknas i funktionen "tolka" blir fel. Detta beror på att jag inte beräknar rätt antal tecken i texten som läses in. Meningen är att man bara ska räkna tecken mellan a/A och z/Z i alfabetet. När jag använder int antal = text.size(); så ger de textens totala längd inklusive blanksteg och övriga tecken. Dessa ska exkluderas och sedan ska man räkna antal tecken i berakna_histogram_abs() och returnera det värdet)!"

 Har någon några idéer på hur jag kan lösa detta? Hur kan jag ändra berakna_histogram_abs() så den returnerar värdet? Jag får inte använda pointers.

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

//

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

 


#include <string>

#include <cctype>

#include <iostream>

#include <fstream>

#include <cmath>

 


using namespace std;

 


// Globala konstanter:

 


// Tips: Anvând de globala konstanterna ANTAL_BOKSTAVER och ANTAL_SPRAK

// istâllet fàr vârdena 26 och 4 i programmet.

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} };

 


// Globala variabler âr ej till¬tna

 


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

// Funktionsdeklarationer:

 


string namn_pa_fil(string namn);

string inlasning(const string& namn);

void berakna_histogram_abs(const string& text, int(&frekvens)[ANTAL_BOKSTAVER]);

void skriv_histogram_abs(const int(&frekvens)[ANTAL_BOKSTAVER]);

void abs_till_rel(const std::string& text, int(&histogram_abs)[ANTAL_BOKSTAVER], double(&histogram_rel)[ANTAL_BOKSTAVER]);

void plotta_histogram_rel(const double(&histogram_rel)[ANTAL_BOKSTAVER]);

void tolka(const double(&histogram_rel)[ANTAL_BOKSTAVER]);

string removeSpaces(string text);

 


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

// Huvudprogram:

 


int main()

{

    string text;

    string filnamn;

    int histogram_abs[ANTAL_BOKSTAVER] = {0};

    double histogram_rel[ANTAL_BOKSTAVER] = {0.0};

 

    filnamn = namn_pa_fil(filnamn);


    text = inlasning(filnamn);   

    berakna_histogram_abs(text, histogram_abs);       

    skriv_histogram_abs(histogram_abs);        

    abs_till_rel(text, histogram_abs, histogram_rel);                //Ber‰kning fˆr att omvandla absolut fˆrekomst (st) av varje bokstav till relativ fˆrekomst (%)

    plotta_histogram_rel(histogram_rel);        //Ett histogram med hur stor relativ fˆrekomst i % av varje bokstav A, b, c...., x, y, z som finns i variabeln 'text'

 


    tolka(histogram_rel);                       //Anger vilket sprÂk som str‰ngen i variabeln 'text' troligen ‰r skriven pÂ

    string sluta;

    while (sluta != "ja")

    {

        cin >> sluta;

    }

 


    return 0;

}

 


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

// Funktionsdefinitioner:

 

string namn_pa_fil(string filnamn)                    //Namn p fil som ska kontrolleras anges

{

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

    getline(cin, filnamn);

    if (filnamn.rfind(".txt") == string::npos)        //Kontrollerar om filnamnet ha .txt - format

    {

        filnamn.append(".txt");                       //L‰gger till ‰ndelsen .txt om det ej angavs

    }

    return filnamn;

}                                                      //Funktionen namn_pa_fil fungerar felfritt

 

 

 

string inlasning(const string& filnamn)         //L‰ser in angiven filen

{

    string tmpString;                                  //Skapar en tempor‰r str‰ng

    string returneradText;

    ifstream fin(filnamn.c_str());                     //Skapar objektet fin

 


    if (!fin)                                       //Kontrollerar om den angiven fil existerar

    {

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

        exit(EXIT_FAILURE);                        //Avslutar programmet

    }

    else

    {

        while (getline(fin, tmpString))

        {

            returneradText += tmpString;

        }

    }

    

    return returneradText;

}


void berakna_histogram_abs(const string& text, int(&frekvens)[ANTAL_BOKSTAVER])

{

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

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

 


    for (char bokstav : text)

    {

        int index;

        if (bokstav >= 'a' && bokstav <= 'z')

        {

            index = bokstav - 'a';

            frekvens[index]++;

        }

 


        if (bokstav >= 'A' && bokstav <= 'Z')

        {

            index = bokstav - 'A';

            frekvens[index]++;

        }

    }

}

 

 

void skriv_histogram_abs(const int(&frekvens)[ANTAL_BOKSTAVER]) //Detta histogram skriver ut den absoluta fˆrekomsten av varje bokstav, tex att det finns 2 st 'R' i variabeln 'text' som innehÂller str‰ngen "Skriv en historia"

{

    //Skriv ut frekvensen fˆr de bokst‰ver som finns

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

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

    {

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

        cout << b << ": " << "\t" << frekvens[i] << endl;

    }

}

 


void abs_till_rel(const std::string& text, 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 = text.size();

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

    {

        histogram_rel[i] = ((double)histogram_abs[i] / antal) * 100.0;     //Bokst‰vernas relativa fˆrekomst ber‰knas, frÂn stycken till andel i %

        //cout << histogram_rel[i] << endl;

    }

}

 

 

 

void plotta_histogram_rel(const double(&histogram_rel)[ANTAL_BOKSTAVER]) //Denna funktion ska nu plotta den relativa fˆrekomsten av varje bokstav, tex att det finns 0,3 % 'R' i variabeln 'text' som innehÂller str‰ngen "Skriv en historia"

{

    char bokstav;

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

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

    {

        double k = 0.5;

        bokstav = 'A' + i;

        cout << bokstav << ": ";

 


        while (k < histogram_rel[i])

        {

            cout << "*";

            k += 0.5;

        }

        cout << endl;

    }

}

 


void 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;

}

Laguna Online 30471
Postad: 17 aug 2020 19:04

Du kan t.ex. skicka med en int antal (via referens) till berakna_histogram_abs, så kan den räkna ut det faktiska antalet tecken. Sedan skickar du 'antal' till de andra funktionerna.

shiela 23 – Fd. Medlem
Postad: 17 aug 2020 20:00
Laguna skrev:

Du kan t.ex. skicka med en int antal (via referens) till berakna_histogram_abs, så kan den räkna ut det faktiska antalet tecken. Sedan skickar du 'antal' till de andra funktionerna.

Menar du så här (plockade ut det relevanta):

int berakna_histogram_abs(const string& text, int(&frekvens)[ANTAL_BOKSTAVER], int& antal);

void skriv_histogram_abs(const int(&frekvens)[ANTAL_BOKSTAVER]);

void abs_till_rel(const std::string& text, int(&histogram_abs)[ANTAL_BOKSTAVER], double(&histogram_rel)[ANTAL_BOKSTAVER], int &antal);

int main()

{

    string text;

    string filnamn;

    int antal;

    int histogram_abs[ANTAL_BOKSTAVER] = {0};

    double histogram_rel[ANTAL_BOKSTAVER] = {0.0};

 

    filnamn = namn_pa_fil(filnamn); //Tar emot filens namn frÂn anv‰ndaren,

    text = inlasning(filnamn);      //l‰ser in str‰ngen "Skriv en historia" som finns i filen liten_fil.txt och lagrar den i variabeln 'text'

    

    berakna_histogram_abs(antal, histogram_abs);       //Ber‰knar hur mÂnga st A, b, c...., x, y, z som finns i variabeln 'text'    skriv_histogram_abs(histogram_abs);         //Ett histogram med hur mÂnga stycken bokst‰ver A, b, c...., x, y, z som finns i variabeln 'text'. Behövs ej skrivas ut i uppgift B, så kommenterar bort raden.

    abs_till_rel(antal, histogram_abs, histogram_rel);                //Ber‰kning fˆr att omvandla absolut fˆrekomst (st) av varje bokstav till relativ fˆrekomst (%)

    plotta_histogram_rel(histogram_rel);        //Ett histogram med hur stor relativ fˆrekomst i % av varje bokstav A, b, c...., x, y, z som finns i variabeln 'text'


    tolka(histogram_rel);                       //Anger vilket sprÂk som str‰ngen i variabeln 'text' troligen ‰r skriven pÂ

    string sluta;

    while (sluta != "ja")

    {

        cin >> sluta;

    }

    return 0;

}

 

int berakna_histogram_abs(const string& text, int(&frekvens)[ANTAL_BOKSTAVER], int &antal)

{

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

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

 


    for (char bokstav : text)

    {

        int index;

        if (bokstav >= 'a' && bokstav <= 'z')

        {

            index = bokstav - 'a';

            frekvens[index]++;

        }

 


        if (bokstav >= 'A' && bokstav <= 'Z')

        {

            index = bokstav - 'A';

            frekvens[index]++;

        }

    }

    return antal;

}

 

void skriv_histogram_abs(const int(&frekvens)[ANTAL_BOKSTAVER]) //Detta histogram skriver ut den absoluta fˆrekomsten av varje bokstav, tex att det finns 2 st 'R' i variabeln 'text' som innehÂller str‰ngen "Skriv en historia"

{

    //Skriv ut frekvensen fˆr de bokst‰ver som finns

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

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

    {

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

        cout << b << ": " << "\t" << frekvens[i] << endl;

    }

}


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

{

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

    {

        histogram_rel[i] = ((double)histogram_abs[i] / antal) * 100.0;     //Bokst‰vernas relativa fˆrekomst ber‰knas, frÂn stycken till andel i %

    }

}

 

Jag får felmeddelande i main() vid anropet för berakna_histogram_abs() och abs_till_rel() som säger "No matching function for call" för båda funktionerna. Detta är min första kurs i programmering, så har en del svårigheter! Ledsen om jag inte förstår så snabbt! :)

Laguna Online 30471
Postad: 17 aug 2020 20:09

Just så, men du får sätta argumentet 'antal' på samma plats i anropet som i deklarationen, t. ex. sist. Nu är det först ibland. 

shiela 23 – Fd. Medlem
Postad: 18 aug 2020 09:56
Laguna skrev:

Just så, men du får sätta argumentet 'antal' på samma plats i anropet som i deklarationen, t. ex. sist. Nu är det först ibland. 

Tusen tack Laguna!! 
Nu funkar det :)

Svara
Close