String Compression C++

I am trying to solve the question to make a C++ code for the question given at the link https://fizzbuzzer.com/better-compression/

The question is restated as follows:

Consider a string, S, that is a series of characters, each followed by its frequency as an integer. The string is not compressed correctly, so there may be many occurrences of the same character. A properly compressed string will consist of one instance of each character in alphabetical order followed by the total count of that character within the string.

For example, the string a3c9b2c1 has two instances where ‘c’ is followed by a count: once with 9 occurrences, and again with 1. It should be compressed to a3b2c10.

Function Description Complete the function betterCompression. The function must return the properly compressed string.

betterCompression has the following parameter: S: a string

Constraints

1 ≤ size of S ≤ 100000

‘a’ ≤ characters in S ≤ ‘z’

1 ≤ frequency of each character in S ≤ 1000

While the solution of the question is given in the website, however, I am not able to understand it. Can someone please give a hint or an idea on how to solve this question, or if there is any alternate and simpler way to do it?
You could make a map

map<char, int> theMap;

You could look at the string. Read the next letter (someChar). Read the numbers (number) that come after it (as far as the next letter) and add it to your count:

theMap[ someChar ] += number;

When you're done, go through the map, building the new string, from a to z, skipping letters for which the count is zero.
Last edited on
How do I read the number next to the string? Because, the number of times a character can occur is not a single digit number, but can be any number between 1 and 1000. Based on the suggestions, I have made the following code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<iostream>
using namespace std;

void bettercompression(string s)
{
char array[2][26] = {0};	
int a[4] = {0}; 
//cout<<s.length();
for(int i = 0; i <s.length(); i++)
{
int p = s[i];
if(p>=97 && p<= 122)
{
a[0]=s[i+1];
  
}


}


}



int main()
{
string s;
getline(cin,s);
bettercompression(s);	
}


Here character 2D array will store the number of occurrences of each character in the string. The integer array may store the number of occurrences of a particular character of the string. Since the maximum occurrences are limited to 1000, therefore, I have taken the size of array to be 4. Please help me, How do I proceed?
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <sstream>
#include <map>
#include <string>
using namespace std;

string fixIt( const string &str )
{
   stringstream ss( str );
   map<char,int> M;
   char c;
   int n;
   while( ss >> c >> n ) M[c] += n;

   string result;
   for ( auto pr : M ) result += pr.first + to_string( pr.second );
   return result;
}


int main()
{
   string tests[] = { "a3c9b2c1", "a10b12c1a18b2" };
   for ( const string &test : tests ) cout << test << " -> " << fixIt( test ) << '\n';
}
Use a string stream. Consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <map>
#include <string>
#include <iostream>
#include <sstream>

int main()
{
	const std::string S("a3c9b2c1");

	std::map<char, size_t> freq;
	std::istringstream iss(S);

	char ch {};

	for (size_t f = 0; iss >> ch >> f; freq[ch] += f);

	for (const auto& [ch, f] : freq)
		std::cout << ch << f;

	std::cout << '\n';
}



a3b2c10

@seeplus, when I compile the code, it is showing some some error, can you please correct it
You need to compile as C++17.

If you can't compile as C++17, update the compiler.

Else try:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <map>
#include <string>
#include <iostream>
#include <sstream>

int main()
{
	const std::string S("a3c9b2c1");

	std::map<char, size_t> freq;
	std::istringstream iss(S);

	char ch {};

	for (size_t f = 0; iss >> ch >> f; freq[ch] += f);

	for (const auto& fr : freq)
		std::cout << fr.first << fr.second;

	std::cout << '\n';
}

Last edited on
"it is showing some some error,"

Future tip for asking for programming help. "There is an error" is useless. Instead, tell people what the error is.
Thanks. I have understood the solution and learn sstream and auto from the above answers for the first time. I will keep all the suggestions in mind next time.
Topic archived. No new replies allowed.