You are here:

C++/Frequency analysis

Advertisement


Question
Hi...

I've an cryptographic related assignment where I need to code frequency analysis program that will count frequency of letter as well as frequency of 2-letters occurrence and position. Example:
Cipher text: dacps sdaps

Result:

Letter
A: 2
B: 0
C: 1
..
Z: 0

2-letters:
DA: 2
PS: 2

I've successfully code the frequency of letter but I'm having problem in 2-letters frequency which I'm only successful searching for first 2-letters occurrence (da). I'm not sure how to shift and find next 2-letters occurrence till the end of the text as well as to keep track of each position. I'm thinking of using struct to store the word, the count and position but I'm not sure how to make my array struct equal to each 2-letters of the word.

Here is my current code:
#include <iostream>         // Standard Library Function needed for input & output
#include<conio.h>          // Standard Library Function needed for getch
#include<string>
#include <iostream>
using namespace std;


#define N 1000

struct wordRepeat          
{
  char word[10];
  int count;
};


int main()
{
   
   char msg[N]={};
   char msg2[N]={};
   string temp="";   
   int charCount[26]={0};
   int wordCount=0;
   
   
   cout<<"Enter cipher text: "<<endl;
   cin.getline(msg, N);
   strupr(msg); //convert msg to upper case
   string text(msg);
   
  


   for(int i=0; i<strlen(msg); i++)
   {  
         if(msg[i]>='A' && msg[i]<='Z')
         charCount[msg[i]-65]++;  //'A' = 65
         //cout<<charCount[msg[i]-65];          
   }
   
   
   cout<<endl<<endl<<"Characters Frequency: "<<endl<<endl;
    for (int i= 0; i < 26; i++)
       cout << char(i + 65) << ": " << charCount[i] << endl;
       
         
    /*for (int i=0; i<text.length(); i++)
    {
    if (text.at(i)!=' ')
     {temp = temp + text.at(i);
     }
      
        
    }
 

    for (int i=0; i<temp.length(); i++)
    {
      
      msg2[i]=temp.at(i);
        
    }
       text = temp;
    
    
    cout<<endl<<"Without space: "<<text<<endl;
    cout<<endl<<"Without space: "<<msg2<<endl;*/
   

   
   cout<<endl<<"Repetition of Words: "<<endl<<endl;
   
  int i, j, M=2, N2 = strlen(msg), count = 0, pos = 0;
     for (i = 0; i < N2; i++)
     {
       for (j = 0; j < M; j++)
         {
         if (msg[i+j] != msg[j]) break;
         if (j == M-1)
         { pos=i+1;
         count++;
         }
     }
         
         
         }
         
   cout<<"Count: "<<count<<" Position: "<<pos;
   
   cout<<endl<<endl;
   system ("pause");
   return 0;
}

Sorry for my bad English. Thank you for reading this e-mail and hope you can give me hint how to solve these problems.

Thank you...

Answer
Rather than use a struct, it would be simpler to use a two-dimensional array to store the frequencies;
frequency[char_one][char_two] would hold the frequency of the char sequence char_one,char_two.
For example, the frequency of 'st' would be in frequency['s']['t'].

Here is the outline:


#include <iostream>
#include <string>
#include <limits>

int main()
{
        enum { NCHARS = 255 } ; // assuming char values are in the range 0-255

        // 2d array of frequency: row is first char, col is second char
        int frequency[NCHARS][NCHARS] = { {0} } ; // init. to zeroes

        std::string text ;
        std::cout << "enter text " ;
        std::getline( std::cin, text ) ;
        const int len = text.size() ; // #chars in input

        for( int i = 0 ; i < (len-1) /*upto the second last char*/ ; ++i )
         ++frequency[ int(text[i]) ][ int(text[i+1]) ] ; // increment frequency

        std::cout << "frequency of 'cd' " << frequency['c']['d'] << '\n' ;
}  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


vijayan

Expertise

my primary areas of interest are generic and template metaprogramming, STL, algorithms, design patterns and c++11. i would not answer questions about gui and web programming.

Experience

about 15 years or so

Education/Credentials
post graduate engineer

©2016 About.com. All rights reserved.