Visa programkörningen /************************************************************************** INLUPP: uppg3B_khb.cpp Exercise: Obligatorisk uppgift 3: Strangar och arrayer Program: SPRAKANALYS - Deluppgift B Author: Krista Hurty Berglund Date: 011125 ABSTRACT: Programmet laser en text fran en textfil och registrerar vilka bokstaver den bestar av. Därefter beraknar programmet forekomsten av varje bokstav som ingar i texten och upprattar ett bokstavshistogram. Sedan jamfors detta histogram med fyra olika spraks bokstavshistogram for att faststalla vilket av de fyra spraken det ar mest troligt att textfilen ar skriven pa. Till sist skrivs ut ett stapeldiagram (stjarnhistogram) over bokstavsandelen for varje bokstav i den analyserade texten. Hanterar fallet med 26 bokstaver A-Z (exklusive de svenska bokstaverna). **************************************************************************/ /************************************************************************** | THE | BEGINNING | :: **************************************************************************/ #include<string.h> #include<fstream.h> #include<math.h> /************************************************************************** | G L O B A L A | K O N S T A N T E R | :: **************************************************************************/ const int MAX_TECKEN = 100000; const int ANTAL_BOKSTAVER = 26; //A-Z const int ANTAL_SPRAK = 4; const int MAX_FILNAMN = 30; 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}}; /************************************************************************** | F U N K T I O N S D E K L A R T I O N E R N A | :: **************************************************************************/ int inlasning( char filnamn[], char text[] ); void berakna_histogram(char text[], double histo[]); void tolkning(double histo[], double kvadrat_summa[]); void namn_pa_fil(char filnamn[], int MAX_FILNAMN); void skriv_histogram(double histo[]); /************************************************************************** | H U V U D P R O G R A M M E T | :: **************************************************************************/ int main() { int fil; char text[MAX_TECKEN]; char filnamn[MAX_FILNAMN]; int histoo[ANTAL_BOKSTAVER]; double histo[ANTAL_BOKSTAVER]; double kvadrat_summa[ANTAL_SPRAK]; cout << "\nAnge namnet pa filen vars text ska sprakanalyseras:\n\n"; cin.getline(filnamn, MAX_FILNAMN); namn_pa_fil(filnamn, MAX_FILNAMN); // Filnamns koll - med|utan andelse ? fil = inlasning(filnamn, text); //"fil" lagrar inlasnings returvarde if (fil) // Alltsa, om returvardet fran inlasning == 1 { berakna_histogram(text, histo); tolkning(histo, kvadrat_summa); skriv_histogram(histo); } return 0; }// SLUT PA MAIN ********************************************************** /************************************************************************** | F U N K T I O N S D E F I N I T I O N E R N A | :: **************************************************************************/ /************************************************************************** | I N L A S N I N G | A V | F I L | :: *************************************************************************** Beskrivning: Funktionen läser in en fil med angivet filnamn och lagrar den i en sträng. Funktionen returnerar värdet ett (1) ifall filen existerar, annars noll (0) Parametrar: filnamn -- sträng som anger namnet på den fil som ska läsas text -- sträng för lagring av filinnehållet **************************************************************************/ int inlasning( char filnamn[], char text[] ) { int i = 0; char tkn; ifstream teckenfil(filnamn); if(teckenfil) { while( teckenfil.get(tkn) ) { text[i] = tkn; i++; } text[i] = '\0'; teckenfil.close(); return 1; } else { cout << "Det finns ingen fil med namnet " << filnamn << endl; return 0; } } /************************************************************************** | B E R A K N I N G | A V | H I S T O G R A M | :: **************************************************************************/ void berakna_histogram(char text[], double histo[]) { int histoo[ANTAL_BOKSTAVER]; int forekomst=0; char versal, gemen; long i, text_tkn, bokstaver=0; // Nollstaller histogram som lagrar bokstavsforekomst: for (i=0; i<ANTAL_BOKSTAVER; i++) {histoo[i]=0;} // Undviker jamforelse av signed och unsigned varden (kompileringsfel): text_tkn = strlen(text); //loper gm alfabetet (versala/gemena) & forekomstraknaren hanger med... for (versal='A', gemen='a'; versal<='Z', gemen<='z'; versal++, gemen++, forekomst++) { //loper gm strangen & raknar/lagrar bokstavsforekomst och -antal. for (i=0; i<=text_tkn; i++) { if ((text[i] == versal) || (text[i] == gemen)) { histoo[forekomst]++; bokstaver++; } } } // Berakning av forekomstandel: for (i=0; i<ANTAL_BOKSTAVER; i++) { histo[i] = 100.0 * histoo[i] / bokstaver; } cout<<"\nResultat for bokstaverna A-Z:\n"; cout<<"\nDet totala antalet bokstaver ar [" << bokstaver <<"].\n\n" << endl; } /************************************************************************** | T O L K N I N G / J A M F O R E L S E | A V | H I S T O G R A M | :: **************************************************************************/ void tolkning(double histo[], double kvadrat_summa[]) { int i, j, sprak=0; double minst, jfr_varde; // Nollstaller kvadratsummearrayen: for (i=0; i<ANTAL_SPRAK; i++){kvadrat_summa[i]=0;} // Kvadrerar och summerar skillnaderna for alla bokstaver: for (j=0; j<ANTAL_BOKSTAVER; j++) { for (i=0; i<ANTAL_SPRAK; i++) { jfr_varde = TOLK_HJALP[i][j]-histo[j]; kvadrat_summa[i] += (jfr_varde * jfr_varde); } } minst = kvadrat_summa[0]; // Faststaller det mest sannolika spraket: for (i=0; i<ANTAL_SPRAK; i++) { if (kvadrat_summa[i]<minst) { sprak=i; minst = kvadrat_summa[i]; } } cout <<"ENGELSKANS kvadtratsumma = " << kvadrat_summa[0]<< endl; cout <<"FRANSKANS kvadtratsumma = " << kvadrat_summa[1]<< endl; cout <<"SVENSKANS kvadtratsumma = " << kvadrat_summa[2]<< endl; cout <<"TYSKANS kvadtratsumma = " << kvadrat_summa[3]<< endl; switch(sprak) { case 0: cout<<"\n\nDet ar mest troligt att spraket ar ENGELSKA.\n\n"; break; case 1: cout<<"\n\nDet ar mest troligt att spraket ar FRANSKA.\n\n"; break; case 2: cout<<"\n\nDet ar mest troligt att spraket ar SVENSKA.\n\n"; break; case 3: cout<<"\n\nDet ar mest troligt att spraket ar TYSKA.\n\n"; break; } } /************************************************************************** | K O N T R O L L | A V | F I L N A M N / F I L A N D E L S E | :: **************************************************************************/ void namn_pa_fil(char filnamn[], int MAX_FILNAMN) { int i; for (i=0; i<MAX_FILNAMN && filnamn[i]!=0; i++) { //Soker efter forsta elementet som tyder pa filslut (i==0), gor inget } if (filnamn[i-1]=='t' && filnamn[i-2]=='x' && filnamn[i-3]=='t' && filnamn[i-4]=='.') { //Kollar om filandelsen ".txt" forekommer i filnamn, gor inget om ja } // Lagg till ".txt" efter filnamn om anvandaren inte uppgett filandelsen: else { if (i<(MAX_FILNAMN-4)) //Kontrollerar att filandelsen ryms. filnamn[i] = '.'; filnamn[i+1] = 't'; filnamn[i+2] = 'x'; filnamn[i+3] = 't'; filnamn[i+4] = 0; } } /************************************************************************** | U T S K R I F T | A V | H I S T O G R A M | :: **************************************************************************/ void skriv_histogram(double histo[]) { int stjarnor; cout<<"@ @ @ @ @ @ @ @ H I S T O G R A M @ @ @ @ @ @ @ @" << endl << endl; cout<<"Bokstavsfordelning:\n" << endl; for (int i=0; i<ANTAL_BOKSTAVER; i++) { cout<< char(i+65) <<" "; stjarnor = int(2 * histo[i]); // Trunkering av antalet stjarnor for (int j=stjarnor; j>0; j--) // Stjarnloop gor stapeldiagram { cout<<'*'; } cout<< endl; } } /************************************************************************** :: | THE END | DELUPPGIFT B | **************************************************************************/ Visa programkörningen