帮我实现一个可回滚的缓冲区

发布于 2024-08-04 10:31:26 字数 1152 浏览 3 评论 0原文

这就是我到目前为止的情况:

我有以下用例(作为公正的 jUnit 测试)来展示我想要实现的目标:

buffer.add(o1);
assertEquals(1, buffer.size());
buffer.mark();
buffer.add(o2);
assertEquals(2, buffer.size());
buffer.add(o3);
assertEquals(3, buffer.size());
assertSame(o1, buffer.get());
assertSame(o2, buffer.get());
assertSame(o3, buffer.get());
buffer.rewind();
// NOTE: It must be possible to enter the same object multiple times
//       into the buffer.
buffer.add(o2);
assertSame(o2, buffer.get());
assertSame(o3, buffer.get());
assertSame(o2, buffer.get());

我尝试使用包装列表(几乎重新发明了轮子)、包装双队列来解决这个问题(这个完全是一团糟),我刚刚失败的第三次尝试是一个包装的 LinkedList,其中除了 rewind() 之外,其他所有东西都可以工作。我最近一次尝试的伪代码是这样的:

if [backBuffer is empty]
    [get latest object]
    increment currentIndex
    if [markIndex < currentIndex]
        [put object to backbuffer]
    return object
else
    [get object from backbuffer at index backBufferIndex]
    increment backBufferIndex
    return object

这根本不起作用,经过一些编辑后,我设法让阅读开始工作,直到调用 rewind() ,所以本质上我第三次编写了一堆冗余代码。在这一点上,我确实感到有点沮丧,因为我从来不擅长算法,这就是我现在来找你的原因:请帮助我实现这个和/或指出我纠正本机 Java API 解决方案,目前我只是感到很困惑,因为我无法让它发挥作用。

This is where I'm so far:

I have the following the following use case (as impartial jUnit test) to show what I want to achieve:

buffer.add(o1);
assertEquals(1, buffer.size());
buffer.mark();
buffer.add(o2);
assertEquals(2, buffer.size());
buffer.add(o3);
assertEquals(3, buffer.size());
assertSame(o1, buffer.get());
assertSame(o2, buffer.get());
assertSame(o3, buffer.get());
buffer.rewind();
// NOTE: It must be possible to enter the same object multiple times
//       into the buffer.
buffer.add(o2);
assertSame(o2, buffer.get());
assertSame(o3, buffer.get());
assertSame(o2, buffer.get());

I have tried solving this using a wrapped List (almost reinvented the wheel), wrapped twin queue (this one was a complete mess), and my third attempt I just failed with was a wrapped LinkedList in which I got everything else working except rewind(). The pseudocode for my latest attempt was something like this:

if [backBuffer is empty]
    [get latest object]
    increment currentIndex
    if [markIndex < currentIndex]
        [put object to backbuffer]
    return object
else
    [get object from backbuffer at index backBufferIndex]
    increment backBufferIndex
    return object

This didn't work at all and after some editing I managed to get reading to work until rewind() was called so essentially I made a bunch of redundant code for the third time. I do feel a bit frustrated at this point since I've never been good with algorithms and that's why I'm coming to you now: Please help me implement this and/or point to me to correct native Java API solution, currently I just feel stumped because I can't get this to work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

森林散布 2024-08-11 10:31:26

假设您有一个简单的 FIFO 对象,它实现了 addgetsize 操作,您可以用伪代码实现此扩展 FIFO,如下所示:

constructor()
{
    FIFO current = new FIFO();
    FIFO alternate = new FIFO();
}

add(Object x)
{
    return current.add(x);
}

get()
{
    Object x = current.get();
    alternate.add(x);
    return x;
}

size()
{
    return current.size();
}

mark()
{
    alternate = new FIFO();
}

rewind()
{
    while (current.size > 0)
    {
        alternate.add(current.get());
    }
    current = alternate;
    alternate = new FIFO();
}

我认为这是一个相当干净的实现。

Assuming you have a simple FIFO object that implements add, get and size operations, you could implement this extended FIFO in pseudocode as follows:

constructor()
{
    FIFO current = new FIFO();
    FIFO alternate = new FIFO();
}

add(Object x)
{
    return current.add(x);
}

get()
{
    Object x = current.get();
    alternate.add(x);
    return x;
}

size()
{
    return current.size();
}

mark()
{
    alternate = new FIFO();
}

rewind()
{
    while (current.size > 0)
    {
        alternate.add(current.get());
    }
    current = alternate;
    alternate = new FIFO();
}

I think this is a fairly clean implementation.

冷夜 2024-08-11 10:31:26

您是否尝试过使用一些附加参数来包装 Java Collection 类型之一。

例如,创建一个包装 ArrayList 的新类。除了数组列表之外,还保留私有成员变量

  • mark - 标记为当前倒带的最后一个索引
  • - get() 上要检索的下一个索引

您还可以添加以下方法

  • get() - 返回数组中的对象列出当前索引并递增当前
  • mark() - 将标记设置为当前的值
  • rewind() - 将当前设置为标记的值

还有一些细节需要解决(如何处理无效索引、标记最初设置为什么)等)但这可能会给你一个好的开始。

Have you tried wrapping one of the Java Collection types with a few additional parameters.

For example, create a new class that wraps an ArrayList. In addition to the array list, keep private member variables

  • mark - the last index that was marked for a rewind
  • current - the next index to retreive on get()

You would also add the following methods

  • get() - Returns the object in the array list at index current and increments current
  • mark() - sets mark to the value of current
  • rewind() - sets current to the value of mark

There are still some details to work out (how are invalid indexes handled, what is mark set to initially, etc.) but that might give you a good start.

相思故 2024-08-11 10:31:26

您能详细说明一下要求吗?我无法理解应该倒带做什么。它应该添加自 mark() 之后添加的所有元素吗?

Could you please elaborate a bit more on the requirement. I was unable to understand what should rewind do. Should it add all elements which were added since mark()?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文