0

I've been trying to come up with an answer to this exercise where I have to count the frequency of characters in a string.

Suppose I have a string "haphqap" and I want the output as "h2a2p2q1".

I am able to achieve with two for loops. If anyone can provide me with some efficient answer.

var strin = "haphqap";

var count = {}

for (var pos = 0; pos < strin.length; pos++) {
  if (!(strin[pos] in count)) {
    count[strin[pos]] = 1;
  } else {
    count[strin[pos]]++;
  }
}

console.log(count) //{ h: 2, a: 2, p: 2, q: 1 }

Using this object I can make a string.

I want to know if there is any another way of doing it?

adiga
  • 34,372
  • 9
  • 61
  • 83
  • 1
    That's a pretty good way to do it, really. – AKX Aug 27 '19 at 10:56
  • 1
    Your approach is already quite efficient and should run in _O(N)_, are you looking for a more efficient approach or just another way to solve your problem? – Nick Parsons Aug 27 '19 at 10:59
  • @NickParsons Here I am using two for loops to reach the result. I was looking for some other way if any where we have only one loop. – Prateek Birla Aug 27 '19 at 11:08
  • @PrateekBirla overall, each loop is going to run _N_ times, _N_ times when constructing the string from the object, so your program will still run in O(N) which is efficient for this sort of thing. At the end of the day, you're going to need some sort of structure to store the occurrences of each letter (you've used an object) and then something to convert that structure back into a string. Adding one additional loop to do this won't cause too much of a performance drain – Nick Parsons Aug 27 '19 at 11:15
  • It's a simple loop through the keys of the object. `let str = ''; for(let key in count) str += key + count[key]` Your approach is the easiest and readable way to do this – adiga Aug 27 '19 at 11:16
  • 1
    @NickParsons I guess you are right.We need one structure to store the count and some loop to convert it back to string. Thanks. – Prateek Birla Aug 27 '19 at 11:30

2 Answers2

0

That's the preferred and simplest way to solve the counting problem. To make a string from that object, use map and join:

const str = Object.entries(count).map(e => e.join("")).join("");

Or:

const str = Object.entries(count).map(([a, b]) => a + b).join("");

Note that there won't be any order because you're using an object.

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
0

You can use reduce.

edit: meet te requirements

//we declare and initialize our string
let myString = "HELLO WORLD";

// we split our variable to get an array
let arrMyString = myString.split('');
// result: [ "H", "E", "L", "L", "O", " ", "W", "O", "R", "L", "D" ]


// now we use Array.reduce 
let myResult = arrMyString.reduce(function(accumulator, currentValue) {

  // accumulator start with empty string, see second parameter of Array.reduce
  let indexCurrentValue = accumulator.indexOf(currentValue);


  if (indexCurrentValue == -1) {
    //char is NOT found in accumulator
    accumulator = accumulator.concat(currentValue, "1");
  } else {
    //char IS found in accumulator
    //step 1 : slice the string
    let myPrettySlice = accumulator.slice(indexCurrentValue);
    //we get the first intrigers before matching any thing else 
    // example myPrettySlice::  g55r99y12h14.slice( [index of y] ) -> y12h14

    let getCountCurrentIndex = /([0-9]{1,})/.exec(myPrettySlice)[0];
    // example would give 12
    //reforming all
    accumulator = accumulator
      .split(currentValue.concat(getCountCurrentIndex))
      .join(currentValue.concat(parseInt(getCountCurrentIndex, 10) + 1));



  }


  return accumulator;
}, "");

console.log(myResult);
  • Thanks for the solution. But here we are getting the object in result i.e. { H: 1, E: 1, L: 3, O: 2, " ": 1, W: 1, R: 1, D: 1 } . To convert it back to string we might use an another loop right? – Prateek Birla Aug 27 '19 at 11:10
  • we can use the reduce function to achieve desired result, lemme update my answer, sorry for bad reading :( –  Aug 27 '19 at 11:13
  • @PrateekBirla i have update'd my answer it's not the most elegant way and there is room for improvement but i hope it helps you on your way –  Aug 27 '19 at 11:48