-3

I'm working on my decode function and I've hit a wall. I dont know if I should pass in the encode function or create a class. My encode function compresses a string, I need the decode function to take that encoded string and expand it.

I've been told that it was the same as doing the encode function. I'm not sure where to go here.

#include<iostream>
#include<string>

using namespace std;

string encode(string str)
{
    string encoding = "";
    int count;

    for  (int i = 0; str[i]; i++)
    {
        count = 1;
        while (str[i]==str[i+1])
        {
            count++, i++;
        }
        encoding += to_string(count) + str[i];
    }
    return encoding;
}

//Im trying to decode the encoded string
//take in a string and count how many of the same characters there are and print
//e.g 
// a3b4c1......would be decoded as aaabbbbc
string decode(string in)
{
    string decoding = "";
    char s;
    int count;
    for (int i = 0; i<in; i++)
    {
        count = 1;
        if (in[i] == 'A')
            count++, i++;
    }

}

int main()
{
    string str = "ABBCC";
    cout << encode(str);
    //cout << decode(str);

}

// My encode functions executes as needed. 1A2B2C
Mode77
  • 991
  • 8
  • 28
Lizan
  • 1
  • 4
  • This looks a bit too simplistic: 1) Your encode function emits count as text, then the character. But your comments suggest it should be character, then count. 2) How would you parse out the count if it's greater than 9 and if the string contains numeric literals? – 500 - Internal Server Error Apr 24 '19 at 16:11
  • About [using namespace std](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)... – Aconcagua Apr 24 '19 at 16:17
  • "a3b4c1......would be decoded as aaabbbbc" but you do not encode that way... – Slava Apr 24 '19 at 16:17
  • It is really bad style to modify the loop variable of a for loop within the loop... – Aconcagua Apr 24 '19 at 16:20
  • It seems like you've gotten a bit ahead of yourself. I would suggest you take a break, put your code aside, go for a walk, and turn the problem over in your head. Re-read the problem and solve small cases on paper (_without_ using code!) Once you feel like you understand what your program needs to do, start small, test often, and make sure you understand what your code actually does. See [How to Debug Small Programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/) by Eric Lippert. – alter_igel Apr 24 '19 at 16:24

2 Answers2

2

Your encoding is not valid because the encoding of "1a" produces "111a" which is also the encoding of 111 consecutive 'a', you need to add a separator between the count and the character

In your decode function you only manage the special case of A and you do not extract the count the encoder put

Note also in

for (int i = 0; i<in; i++)
{
    count = 1;
    if (in[i] == 'A')
        count++, i++;
}

you always reset count to 1

You need to first extract the count (with the problem I signal at the beginning of my answer) then duplicate the letter 'count' times

It is useless to do string encoding = ""; because the constructor of std::string make it empty, can be just string encoding;

You need to decode an encoded string, this is not what you do in your main where you try to decode the initial string


A corrected version can be :

#include<iostream>
#include<string>
#include <sstream>

using namespace std;

string encode(string str)
{

  stringstream encoding;
  int count;

  for  (int i = 0; str[i]; i++)
  {
    count = 1;
    while (str[i]==str[i+1])
    {
      count++, i++;
    }
    encoding << count << ' ' << str[i];
  }
  return encoding.str();
}

string decode(string in)
{
  stringstream is(in);
  string decoding;
  int n;
  char c;

  while (is >> n >> c)
  {
    while (n--)
      decoding += c;
  }

  return decoding;
}

int main()
{
  cout << encode("ABBCC2a") << endl;
  cout << decode(encode("ABBCC2a")) << endl;

  return 0;
}

Compilation and execution :

pi@raspberrypi:/tmp $ g++ -pedantic -Wall -Wextra e.cc
pi@raspberrypi:/tmp $ ./a.out
1 A2 B2 C1 21 a
ABBCC2a
Aconcagua
  • 24,880
  • 4
  • 34
  • 59
bruno
  • 32,421
  • 7
  • 25
  • 37
  • thank you and everyone for the feeback. Would you mind clarifying for me what the code "while(is>>n>>c)" means in the decode function – Lizan Apr 24 '19 at 19:53
  • @Lizan _is_ is an input stream (as _std::cin_) initialized with the contents of _in_, so `is>>n` extract/read an _int_ and `is >> c` a _char_ because of the type of the variables, and it is possible to pipe them as `is>>n>>c` exactly like it is possible to do `std::cout << 123 << 'c'` to print. Furthermore if an error occurs while extracting the _int_ or the _char_ the expression values _false_, so finally `while (is >> n >> c)` reads an _int_ in _n_ and a _char_ in _c_ until EOF corresponding to the end of the string used to initialize the _stringstream_. – bruno Apr 24 '19 at 21:00
  • @Lizan Note also the spaces/tab are bypassed on the read, so the space placed between the count and the letter is not get for _c_ but allows to stop to read the _int_ before to read the letter perhaps being a digit – bruno Apr 24 '19 at 21:03
0

Run-length-encoding – but in a very strange way!

encoding += to_string(count) + str[i];

Let's encode string "sssssssssss"; it will result in a string with array representation of

{ '1', '1', 's', 0 } // string "11s"

(I chose this representation deliberately, you'll see later...)

The problem is that you wouldn't be able to encode strings containing digits: "1s" will result in

{ '1', '1', '1', 's', 0 } // string "111s"

but how would you want to distinguish if we need to decode back to "1s" or into a string solely containing 111 s characters?

Try it differently: A character actually is nothing more than a number as well, e. g. letter s is represented by numerical value 115 (in ASCII and compatible, at least), the digit 7 (as a character!) by numerical value 55. So you can simply add the value as character:

encoding += static_cast<unsigned char>(count) + str[i];

There are some corner cases, unsigned char cannot hold numbers greater than 255, so a string having more subsequent equal characters would have to be encoded e. g. as

{ 255, 's', 7, 's', 0 } // 262 times letter s

Note the representation; 255 and 7 aren't even printable characters! Now let's assume we encoded a string with 115 times the letter s:

{ 115, 's', 0 } // guess, as string, this would be "ss"...

To catch, you would simply check explicitly your counter for reaching maximum value.

Now decoding gets much simpler:

size_t i = 0;
while(i < encoded.size())
{
    unsigned char n = encoded[i];
    ++i;
    while(n--)
        decoded += encoded[i];
    ++i;
}

Totally simple: first byte always as number, second one as character...

If you insist on numbers being encoded as string (and encode only strings not containing digits), you could use a std::istringstream:

std::istringstream s(encoded);
unsigned int n;
char c;
while(s >> n >> c)
{
    while(n--)
        decoded += encoded[i];
}

OK, it is not symmetric to your encoding function. You could adapt the latter to be so, though:

std::ostringstream s;

for(;;) // ...
{
    unsigned int count = 1;
    // ...
    s << count << str[i];
}
Aconcagua
  • 24,880
  • 4
  • 34
  • 59