RLE序列,设置一个值

时间:2011-10-16 17:30:57

标签: java arraylist run-length-encoding

说我有一个任意的RLE序列。 (对于那些不知道的人,RLE将[4 4 4 4 4 6 6 1 1]这样的数组压缩成[(5,4)(2,6)(2,1)]。首先是数字a运行中的特定整数,然后是数字本身。)

如何在不解压缩整个事物的情况下确定在给定索引处设置值的算法?例如,如果设置(0,1),则RLE将变为[(1,1)(4,4)(2,6)(2,1)]。 (在集合中,第一个值是索引,第二个值是值)

此外,我已将此压缩序列划分为Entries的ArrayList。也就是说,每个条目都是以下之一:(1,1)它具有金额和价值。

我正在尝试找到一种有效的方法来做到这一点,现在我可以想到如果语句被认为是干净的那么方法太多了。有很多可能的变化:例如,如果给定值拆分现有条目,或者它与现有条目具有相同的值,等等......

非常感谢任何帮助。我现在正在研究一种算法,这里有一些算法:

while(i<rleAL.size() && count != index)
    {
        indexToStop=0;
        while(count<index || indexToStop == rleAL.get(i).getAmount())
        {
            count++;
            indexToStop++;
        }

        if(count != index)
        {
            i++;
        }
    }

正如你所看到的那样越来越邋...... ......

谢谢!

1 个答案:

答案 0 :(得分:1)

RLE通常对更新有害,完全是出于上述原因。将ArrayList更改为LinkedList没有多大帮助,因为LinkedList在除插入之外的所有内容中都非常慢(即使使用插入,您也必须使用例如ListIterator来保存对特定位置的引用)。

谈到原始问题,但没有必要解压缩所有问题。您所需要的只是找到正确的位置(总计计数),这是线性时间(考虑跳过列表以使其更快),之后您将只有四个选项:

  1. 你在一个区块中,这个区块与你想要保存的区号相同。
  2. 你在一个街区内,而且数量不同。
  3. 你在街区的开头或结尾,这个数字与街区不同,但与邻居相同。
  4. 你在街区的开头或结尾,这个数字既不是街区也不是邻居的数字。
  5. 行动是一样的,显然:

    1. 什么都不做
    2. 更改块中的计数器,添加两个块
    3. 以两个方块更改计数器
    4. 在一个区块中更改计数器,插入一个新的
    5. (注意,如果你有跳过列表,你也必须更新它们。)

      更新:如果要更新的块长度为1,则更有趣。尽管如此,它仍然是微不足道的:在任何情况下,变化都限制在最多三个街区。