如何设置我的解码功能以接受编码的字符串?

时间:2019-04-24 16:06:05

标签: c++ run-length-encoding

我正在使用我的解码功能,但是遇到了麻烦。我不知道是否应该传递编码函数或创建一个类。我的编码功能压缩了一个字符串,我需要解码功能来获取该编码的字符串并将其扩展。

有人告诉我,这和编码功能是一样的。我不确定要去哪里。

#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

2 个答案:

答案 0 :(得分:2)

您的编码无效,因为“ 1a”的编码会产生“ 111a”,这也是111个连续“ a”的编码,您需要在计数和字符之间添加分隔符

在解码功能中,您仅管理A的特殊情况,而不提取编码器放置的计数

也请注意

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

您始终将 count 重置为1

您需要首先提取计数(问题是我在回答开始时发出的信号),然后重复字母“ count”的次数

string encoding = "";没用,因为std::string的构造函数将其设为空,可以只是string encoding;

您需要解码一个编码的字符串,这不是您在尝试初始化初始字符串的 main 中所做的


更正的版本可以是:

#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;
}

编译和执行:

pi@raspberrypi:/tmp $ g++ -pedantic -Wall -Wextra e.cc
pi@raspberrypi:/tmp $ ./a.out
1 A2 B2 C1 21 a
ABBCC2a

答案 1 :(得分:0)

游程长度编码–但是以一种非常奇怪的方式!

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

让我们编码字符串"sssssssssss";它将导致一个字符串,其数组表示为

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

(我是故意选择此表示形式的,稍后您会看到...)

问题是您将无法对包含数字的字符串进行编码:"1s"将导致

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

但是如果我们需要解码回"1s"或解码为仅包含111个s字符的字符串,您将如何区分?

以其他方式尝试:字符实际上也不过是数字而已,例如e。 G。字母s由数值115(至少是ASCII且兼容),数字7(作为字符!)由数值55表示。因此,您可以简单地将值添加为字符:

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

在某些特殊情况下,无符号char不能容纳大于255的数字,因此必须将具有更多后续相等字符的字符串编码为e。 G。

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

注意表示形式; 255和7甚至都不是可打印字符!现在,假设我们使用115倍于字母s的字符串进行编码:

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

要捕获,只需简单地检查计数器是否达到最大值即可。

现在解码变得更加简单:

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

非常简单:第一个字节始终作为数字,第二个字节始终作为字符...

如果您坚持将数字编码为字符串(并且仅编码不包含数字的字符串),则可以使用std::istringstream

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

好的,它与您的编码功能不对称。不过,您可以将后者修改为:

std::ostringstream s;

for(;;) // ...
{
    unsigned int count = 1;
    // ...
    s << count << str[i];
}