【问题标题】:C# encoding text RLE methodC#编码文本RLE方法
【发布时间】:2015-11-27 14:12:08
【问题描述】:

我正在尝试通过“删除”重复字节来打包给定的字节数组,如下所示:

  1. 入口255 1 1 4 4 4 4 4 200 15 10
  2. 输出 1x255 2x1 5x4 1x200 1x15 1x10 => 255 1 1 5 4 200 15 10

如果一个字节重复超过 3 次,我用计数器替换它。

我首先制作了一个没有重复值的临时字节列表,并列出了出现次数。不过我的柜台有问题:

public static void compressBlock(List<byte> buffer)
    {
        byte marker = buffer.Last();

        int counter = 1;


        byte[] buffer_ar = new byte[buffer.Count];
        buffer_ar = buffer.ToArray();

        List<byte> temp = new List<byte>();
        List<int> tmp = new List<int>();


       int indeks = 0;
            while (true)
            {


                if (buffer_ar[indeks] == buffer_ar[indeks + 1])
                {
                    counter++;

                    if (buffer_ar[indeks] != buffer_ar[indeks + 1])
                    {
                        temp.Add(buffer_ar[indeks]);
                        tmp.Add(counter);
                        //counter = 1;
                    }


                }

                else
                {
                    //counter = 1;
                    temp.Add(buffer_ar[indeks]);
                    tmp.Add(counter);

                }

                indeks++;
                //counter = 1;

                if (buffer_ar.Length -1 <= indeks) { break; }

            }

作为我的输出:

字节列表:255 1 4 200 15 10

整数列表:1 2 6 6 6 6

我知道我必须在某个时候重置计数器,但是当我这样做作为 int 列表的输出时,我有:1 1 1 1 1 1。

有人能给我指出正确的方向吗?

【问题讨论】:

  • 旁注:所以不同输入`255 1 1 4 4 4 4 4 200 15 10`和255 1 1 5 4 200 15 10应该产生相同的输出 255 1 1 5 4 200 15 10?
  • 255 1 1 5 4 200 15 10
  • 假设255 1 1 5 4 200 15 10 输入,那么输出是什么?
  • 在我的 byte[] temp 上它将是:255 1 5 4 200 15 10,在最终压缩块上它将是 255 1 1 5 4 200 15 10 因为添加计数器没有意义,因为它不会减少字节数
  • 并且,请参阅:不同的输入,即255 1 1 4 4 4 4 4 200 15 10255 1 1 5 4 200 15 10将产生相同的输出255 1 1 5 4 200 15 10,那么怎么能你解码它回来了吗? 5 4 应该“按原样”解码5 4 还是扩展为4 4 4 4 4

标签: c# bytearray counter


【解决方案1】:

您的实施存在一些问题:

  1. 解码是不可能的,因为不同的输入1 1 1 14 1产生相同的输出4 1
  2. 如果相同的项目出现超过 255 (255 == Byte.MaxValue) 次怎么办?
  3. 最好使用通用IEnumberable&lt;Byte&gt; 然后concrete List&lt;Byte&gt;
  4. 您不需要任何缓冲区,只需计算最后一个项目的出现次数。

    public static IEnumerable<Byte> RleEncode(IEnumerable<Byte> source) {
      if (null == source)
        throw new ArgumentNullException("source");
    
      const int threshold = 3;
    
      Byte current = 0;
      int count = 0;
    
      foreach (var item in source) 
        if ((count == 0) || (current == item)) {
          current = item; 
          count += 1;
        }
        else {
          if (count <= threshold)
             for (int i = 0; i < count; ++i)
               yield return current;
          else {
            for (int i = 0; i < count / Byte.MaxValue; ++i) {
              yield return Byte.MaxValue;
              yield return current;
            }
    
            if (count % Byte.MaxValue != 0) {
              yield return (Byte) (count % Byte.MaxValue);
              yield return current;
            }
          }
    
        current = item;
        count = 1;
      }
    
      // Tail
      if (count <= threshold)
        for (int i = 0; i < count; ++i)
           yield return current;
      else {
        for (int i = 0; i < count / Byte.MaxValue; ++i) {
          yield return Byte.MaxValue;
          yield return current;
        }
    
        if (count % Byte.MaxValue != 0) {
          yield return (Byte) (count % Byte.MaxValue);
          yield return current;
        }
      }
    }
    

测试

  List<Byte> source = new List<Byte> {
    255, 1, 1, 4, 4, 4, 4, 4, 200, 15, 10
  };

  // 255 1 1 5 4 200 15 10 
  String test = String.Join(" ", RleEncode(source));

【讨论】:

  • 我刚刚在上面的评论中解释了解码问题。但你是对的'如果相同的项目出现超过 255 次' - 我没有想到这一点。
  • 无论如何你的回答对我帮助很大。谢谢!
  • 好吧,你必须修改它(至少添加标记);我提出了不止255项问题解决方案:想象输入文本是1..1 (300) times;你会如何编码它? 300不能编码为单个byte;我已经这样输出了:255 1 45 1,但是还有其他解决方案。不客气,你问了一个很好的问题,有点设计不足,恕我直言,
  • 在字节满后中止并写一个新的重复?这并不难......
【解决方案2】:

你永远不会到这里

if (buffer_ar[indeks] != buffer_ar[indeks + 1])

因为它放在倒置的if里面

if (buffer_ar[indeks] == buffer_ar[indeks + 1])

所以你永远不会将计数器添加到你的数组中

【讨论】:

    猜你喜欢
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    • 2014-04-23
    相关资源
    最近更新 更多