stuff-from-scratch/src/compression/RunLengthEncoder.h

111 lines
2.3 KiB
C
Raw Normal View History

2022-11-21 17:45:12 +00:00
#pragma once
#include "StringUtils.h"
#include <vector>
#include <string>
class RunLengthEncoder
{
public:
std::string encode(const std::string& string)
{
std::string ret;
if (string.empty())
{
return ret;
}
char working_char{0};
unsigned count = 1;
for(unsigned idx=0; idx<string.size(); idx++)
{
auto c = string[idx];
if (idx == 0)
{
working_char = c;
continue;
}
if (c == working_char)
{
count++;
}
else
{
insertCharacter(ret, working_char, count);
working_char = c;
count = 1;
}
}
insertCharacter(ret, working_char, count);
return ret;
}
std::string decode(const std::string& string)
{
std::string ret;
if (string.empty())
{
return ret;
}
unsigned count{0};
while(count < string.size())
{
auto c = string[count];
if (c == mDelimiter)
{
count++;
std::string reps;
char working_char{0};
while(count < string.size())
{
auto rep_char = string[count];
count++;
if (StringUtils::IsAlphabetical(rep_char))
{
working_char = rep_char;
break;
}
else
{
reps += rep_char;
}
}
for (unsigned idx=0; idx<std::stoul(reps); idx++)
{
ret += working_char;
}
}
else
{
ret += c;
count++;
}
}
return ret;
}
private:
void insertCharacter(std::string& output, char c, unsigned count)
{
if (count >= 3)
{
output += mDelimiter + std::to_string(count) + c;
}
else
{
for (unsigned jdx=0;jdx<count; jdx++)
{
output += c;
}
}
}
char mDelimiter {'@'};
};