Most common words in a text file I've made a program that outputs you the most common word in txt file. Does anybody know how to optimize it so that it would work for bigger files and run faster?

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;fstream&gt;
#include &lt;cstdlib&gt;
#include &lt;vector&gt;
#include &lt;algorithm&gt;
#include &lt;math.h&gt;

using namespace std;

int main()
{
    ifstream in("file.txt");

    if(!in){
        cerr &lt;&lt; "Could not open file.txt.";
        return EXIT_FAILURE;
    }

    string str, str2, strn, tab[10000], tab2[10000];
    int i, k, j, n, l, tabl;
    char c = 179;
    vector&lt;int&gt; tabs;
    vector&lt;string&gt; stringi;

    while(getline(in, str2)){
        str += str2;
        str += ' ';
    }
    k = 0;
    for(i = 0; i &lt; str.length(); i++){
        if(str[i] != ' ' &amp;&amp; str[i] != '.' &amp;&amp; str[i] != '\t' &amp;&amp; str[i] != ','
           &amp;&amp; str[i] != ';' &amp;&amp; str[i] != ':' &amp;&amp; str[i] != '}' &amp;&amp; str[i] != '{'){
            tab[k] += tolower(str[i]);
        }else{
            k++;
        }
        if(str[i] == '.' || str[i] == '\t' || str[i] == ',' || str[i] == ';'
        || str[i] == ':' || str[i] == '}' || str[i] == '{') {
            k--;
        }
    }
    tabl = k;

    k = 0;
    for(i = 0; i &lt; tabl; i++){
        for(j = 0; j &lt; tabl; j++){
            if(tab[i] == tab[j]){
                k++;
            }
        }
        tabs.push_back(k);
        k = 0;
    }
    for(i = 0; i &lt; tabl; i++){
        for(j = 0; j &lt; tabl-1; j++){
            if(tab[j] &lt; tab[j+1]){
                n = tabs.at(j);
                tabs.at(j) = tabs.at(j+1);
                tabs.at(j+1) = n;
                strn = tab[j];
                tab[j] = tab[j+1];
                tab[j+1] = strn;
            }
        }
    }
    for(i = 0; i &lt; tabl; i++){
        for(j = 0; j &lt; tabl-1; j++){
            if(tabs.at(j) &lt; tabs.at(j+1)){
                n = tabs.at(j);
                tabs.at(j) = tabs.at(j+1);
                tabs.at(j+1) = n;
                strn = tab[j];
                tab[j] = tab[j+1];
                tab[j+1] = strn;
            }
        }
    }
    tab2[0] = tab[0];
    for(i = 0; i &lt; tabl; i++){
        if(tab[i] != tab[i+1]){
            tab2[i] = tab[i+1];
        }
    }
    k = 1;
    l++;
    for(i = 0; i &lt; tabl; i++){
        if(!tab2[i].empty()){
            l++;
        }
    }
    cout &lt;&lt; "------------------------------------" &lt;&lt; endl;
    cout &lt;&lt; "|---&gt;TABLE OF MOST COMMON WORDS&lt;---|" &lt;&lt; endl;
    cout &lt;&lt; "------------------------------------" &lt;&lt; endl;
    for(i = 0; i &lt; tabl; i++){
        if(!tab2[i].empty() &amp;&amp; k &lt;= 20 ){
            cout &lt;&lt; c &lt;&lt; k++ &lt;&lt; "." &lt;&lt; '\t' &lt;&lt; c &lt;&lt; tab2[i] &lt;&lt; '\t' &lt;&lt; c &lt;&lt; "*" &lt;&lt;
            tabs.at(i+1)
            &lt;&lt; '\t'  &lt;&lt; c &lt;&lt; roundf(((float)tabs.at(i+1)*100/l)*100)/100 &lt;&lt; "%" &lt;&lt;
            endl;
        }
    }
    cout &lt;&lt; "------------------------------------" &lt;&lt; endl ;
    cout &lt;&lt; "|-----&gt;Dif. strings: " &lt;&lt; '\t' &lt;&lt; l &lt;&lt; "&lt;-------|" &lt;&lt; endl ;
    cout &lt;&lt; "------------------------------------" &lt;&lt; endl;

    return 0;
}


Output image:
Declare variables as late as possible. int i, k, j, n, l, tabl; What do these variables do? It is quite difficult to figure that out. If you declare and initialize them when needed it would be clear.
Keep variables as local as possible. A loop such as for(i = 0; i &lt; str.length(); i++) makes me think the result of i is required later which it is not (I think). Prefer for (int i = 0; i &lt; str.length(); i++).
People do not like using namespace std;.
tab[10000] and char c = 179; have magic numbers. Why 10000 and 179? Since you know how to use vector it is hard to guess why you thought having 10000 stings twice is a good idea.
This seems to be a major performance problem (you are supposed to profile because obvious performance problems can get fixed by the optimizer and the line between what the optimizer thinks is obvious and which is not is very hard to predict):

while(getline(in, str2)){
    str += str2;
    str += ' ';
}


This produces a string to hold a single line. Then it adds a line, but it is out of memory, so it allocates new memory for 2 lines, copies 2 lines and throws the memory for 1 string away. Then it allocates memory for 3 lines, copies 3 lines and throws 2 lines of memory away. When you start allocating memory for 100 lines, copy 100 lines and throw 99 lines worth of memory away things get slow. I would suggest counting words one line at a time instead of reading the whole file at once.
Use functions. Some people do not allow more than 10 lines per function, otherwise it must be re-factored into multiple functions. 10 lines are a bit strict, but you should separate concerns. One function to get the input, one function to do the word counting, one function to do the output. Maybe some functions will be too complicated and need to be split up further. The point is that if you need to change a part of the program you see from the function names where to change what.
I looked at your loops and indexes and I don't even want to try to understand what is going on. You can replace almost all of that with a map&lt;string, int&gt;.


This is what I came up with (it is 4:35 am here). My code kind of deserves a review of its own because it makes me look a bit hypocritical.

    #include &lt;iostream&gt;
    #include &lt;string&gt;
    #include &lt;map&gt;
    #include &lt;algorithm&gt;
    #include &lt;cctype&gt;
    #include &lt;vector&gt;
    #include &lt;sstream&gt;
    #include &lt;fstream&gt;
    #include &lt;iomanip&gt;

    void removeNonAlphabeticalCharacters(std::string &amp;s){
        s.erase(std::remove_if(std::begin(s), std::end(s), [](char c){ return !isalpha(c); }), std::end(s));
    }

    template&lt;class Iterator&gt;
    //constraint: Iterator::value_type == std::pair&lt;std::string, int&gt;
    void displayRanking(Iterator begin, Iterator end, int wordcount){
        int index = 1;
        while (begin != end){
            std::cout &lt;&lt; '|' &lt;&lt; index &lt;&lt; ".\t|" &lt;&lt;
                begin-&gt;first &lt;&lt; "\t|" &lt;&lt; begin-&gt;second &lt;&lt; "\t|" &lt;&lt; 
                std::fixed &lt;&lt; std::setprecision(2) &lt;&lt; begin-&gt;second * 100.f / wordcount &lt;&lt; "%\n";
            ++begin;
            index++;
        }
    }

    int main(){
        std::map&lt;std::string, int&gt; wordcounter;
        std::string input;
        int totalwords = 0;
        std::ifstream in("file.txt");
        while (in &gt;&gt; input){
            removeNonAlphabeticalCharacters(input);
            wordcounter[input]++;
            totalwords++;
        }
        if (totalwords == 0){
            std::cout &lt;&lt; "failed reading words from file\n";
            return 0;
        }

        //how many words to display in the ranking
        const int top = std::min((size_t)20, wordcounter.size());
        //copy wordcounter to vector for sorting
        std::vector&lt;std::pair&lt;std::string, int&gt;&gt; toplist;
        toplist.reserve(wordcounter.size());
        std::copy(std::begin(wordcounter), std::end(wordcounter), std::back_inserter(toplist));
        auto comparator = [](const std::pair&lt;std::string, int&gt; &amp;lhs, const std::pair&lt;std::string, int&gt; &amp;rhs){return lhs.second &gt; rhs.second; };
        std::partial_sort(std::begin(toplist), std::begin(toplist) + top, std::end(toplist), comparator);

        displayRanking(std::begin(toplist), std::begin(toplist) + top, totalwords);
    }


There are many ways to improve readability and performance still, but let me know how long my code takes with your input file.