String Compression C++

Apr 23, 2021 at 11:32am
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?
Apr 23, 2021 at 11:35am
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 Apr 23, 2021 at 11:36am
Apr 23, 2021 at 11:43am
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 Apr 23, 2021 at 11:54am
Apr 23, 2021 at 11:55am
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';
}
Apr 23, 2021 at 11:58am
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

Apr 23, 2021 at 12:51pm
@seeplus, when I compile the code, it is showing some some error, can you please correct it
Apr 23, 2021 at 1:00pm
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 Apr 23, 2021 at 1:05pm
Apr 23, 2021 at 1:25pm
"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.
Apr 23, 2021 at 6:52pm
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.