423,309 Members | 2,163 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 423,309 IT Pros & Developers. It's quick & easy.

how can you create a histogram which outputs how many times a character appeared in a

P: 1
create a new class on JavaScript called “MyString” that computes a histogram representing the number of times each letter of the alphabet is in a given text.
Nov 30 '17 #1
Share this Question
Share on Google+
1 Reply


gits
Expert Mod 5K+
P: 5,173
well - it looks like an assignment but i guess we can answer it now after a few months to help those that might find it through a search or such. a pretty quick and straight forward solution to that could look like this:

Expand|Select|Wrap|Line Numbers
  1. class TextHandler {
  2.  
  3.     constructor(txt) {
  4.  
  5.         if (typeof txt !== 'string') {
  6.             throw 'cant create object - param has to be a string';
  7.         }
  8.  
  9.         this.txt = txt;
  10.     }
  11.  
  12.     __initList() {
  13.  
  14.         return {
  15.             a:0, b:0, c:0, d:0, e:0, f:0, g:0,
  16.             h:0, i:0, j:0, k:0, l:0, m:0, n:0,
  17.             o:0, p:0, q:0, r:0, s:0, t:0, u:0,
  18.             v:0, w:0, x:0, y:0, z:0
  19.         };
  20.     }
  21.  
  22.     get histogram() {
  23.  
  24.         let charHistogram = this.__initList();
  25.  
  26.         for (let i in charHistogram) {
  27.  
  28.             let re = new RegExp('([' + i + '])', 'gi');
  29.             let ma = this.txt.match(re);
  30.  
  31.             charHistogram[i] = ma !== null ? ma.length : 0;
  32.         }
  33.  
  34.         return charHistogram;
  35.     }
  36. }
it should fulfill the minimum requirements that can be read from the post - and it should be adapted to what the real! requirements would be.

PS: usage could look like:
Expand|Select|Wrap|Line Numbers
  1. new TextHandler('foobar').histogram;
PPS: since i now was interested :) it appears that such a task can be optimized much by using another approach that simply reduces the needed operations - so during every loop-step we could reduce the text by just replacing the already checked characters like that:

Expand|Select|Wrap|Line Numbers
  1.  
  2.     get histogram() {
  3.  
  4.         let charHistogram = this.__initList();
  5.         let txt = this.txt;
  6.  
  7.         for (let i in charHistogram) {
  8.  
  9.             let le = txt.length;
  10.             let re = new RegExp('([' + i + '])', 'gi');
  11.  
  12.             txt = txt.replace(re, '');
  13.  
  14.             charHistogram[i] = le - txt.length;
  15.         }
  16.  
  17.         return charHistogram;
  18.     }
  19.  
that made creating the histogram much faster with longer texts - i roughly measured 5x faster execution times with that method (text used for measurement had 21793 characters). note that this consumes the text we use for that - thats why i dont operate on it but assign it to a local variable - and the nice side effect would be that we can have an easy access to the residue at the end that we didnt count in - in the above case all characters like special chars or numbers and such (we count only whats in the initial list).

PPPS: could even be more optimized - probably slightly only but still - by ordering our counting map according to the common frequency of letters in a text in a language. i ordered the list according to here:

https://en.wikipedia.org/wiki/Letter_frequency

that squeezed out another few milliseconds per pass - was only noticable when i increased the text size though to 130758 characters. got roughly 15% faster execution times with it by just starting with the letter e and t instead of a and b.
Mar 15 '18 #2

Post your reply

Sign in to post your reply or Sign up for a free account.