简体   繁体   English

C#编码文本RLE方法

[英]C# encoding text RLE method

I'm trying to pack a given byte array by 'removing' repeated bytes, something like this: 我正在尝试通过“删除”重复的字节来打包给定的字节数组,如下所示:

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

If one byte is repeated more than 3 times I replace it with the counter. 如果重复一个字节超过3次,我将其替换为计数器。

I began with making a temporary byte list with no repeated values and list with numbers of appearances. 我从制作一个没有重复值的临时字节列表和带有出现次数的列表开始。 I've got a problem with the counter though: 我的柜台有问题:

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

            }

As the output I have: 作为输出,我有:

byte list: 255 1 4 200 15 10 字节列表:255 1 4 200 15 10

int list: 1 2 6 6 6 6 整数列表:1 2 6 6 6 6

I know I have to reset the counter at some point, but when I do that as the output of the int list I have: 1 1 1 1 1 1. 我知道我必须在某个时候重置计数器,但是当我将其作为int列表的输出时,我有:1 1 1 1 1 1。

Could someone point me in the right direction to do that? 有人可以指出我正确的方向吗?

You will never get here 你永远不会到这里

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

because it is placed inside the inverted if 因为它被放置在倒立的内部

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

So you would never add the counter to your array 因此,您永远不会将计数器添加到数组中

There're some issues with you implementation: 您的实现存在一些问题:

  1. Decode is impossible since different inputs like 1 1 1 1 and 4 1 produce the same output : 4 1 解码是不可能的,因为像1 1 1 14 1这样的不同输入会产生相同的输出4 1
  2. What if the same items appears more than 255 ( 255 == Byte.MaxValue ) times? 如果相同的项目出现超过255次255 == Byte.MaxValue )次该怎么办?
  3. Better use general IEnumberable<Byte> then concrete List<Byte> 最好使用常规IEnumberable<Byte>然后使用concrete List<Byte>
  4. You don't need any buffer , just count the last item occurence. 您不需要任何缓冲区 ,只需计算最后一项发生的次数即可。

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

Test 测试

  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));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM