increment an infinite binary counter [closed]

本秂侑毒 提交于 2019-12-12 02:08:16

问题


Taken from coding interview:

How would you implement an infinite binary counter with increment in O(1) time complexity?

I thought to calculate the first and second position of the rightmost 0, but I'm not sure how to implement this.

"Infinite counter" means you can increment an infinite number of times (greater than MAX_INT).


回答1:


For a binary counter...

If you want to keep the counter in a "normal" bit pattern, you can't, fundamentally - at least not for always O(1) rather than amortized O(1).

If it's an infinite counter, it can have arbitrarily many bits. That means you can have a number of N bits, all of which are 1. Incrementing that counter means setting all those bits to 0, which can reasonably be assumed to be an O(N) operation.

The only reason we can consider an increment to be O(1) in "normal" computing is that usually deal with fixed-size types, where we can say (for example) "At most 32 bits will need to change - that's a constant, so it's conceivably an O(1) operation."

For just a counter...

On the other hand, if you just want to be able to increment in O(1) time, you have infinite memory, and you don't care how long it takes to recover the value, you can do it, just by effectively using a linked list whose length is the counter size.

For example, in C#:

public DodgySolution
{
    public static DodgySolution Zero = new DodgySolution(null);

    private DodgySolution tail;

    private DodgySolution(DodgySolution tail)
    {
        this.tail = tail;
    }

    // This bit is O(1)
    public DodgySolution Increment()
    {
        return new DodgySolution(this);
    }

    // This bit isn't...
    public BigInteger ToBigInteger()
    {
        return tail == null ? BigInteger.Zero
                            : BigInteger.One + tail.ToBigInteger();
    }
}

Even this assumes that a reference assignment is O(1) though - which could become tricky with an infinite number of objects...




回答2:


  • Use some kind of array storage with a doubling strategy. This means allocations are amortized O(1)
    A linked list should work as well.
  • Use trivial schoolbook addition. Carries get exponentially rare for higher bits. Average cost for carries is 1+0.5+0.25+... = 2 which O(1)

So a straight forward implementation has amortized O(1) performance. The only issue is that you need mutable storage.

When looking at individual increment operations of a number n, then the average time is O(1) but the worst case is O(log(n)). Memory usage is O(log(n)).

var counter=new List<bool>{false};

void Inc()
{
  while(counter[i])
  {
      counter[i]=false;
      i++;
  }
  if(i==counter.Length)
    counter.Add(true);
  else
    counter[i]=true;
}



回答3:


If the question is only asking for increment of O(1) counter without any other limitations your counter can be implemented as a linked list of numbers and the sum of items is the value of your counter.

Incrementing will be equivalent to adding a 1 to the last item or adding a new item=1 if the value before is greater than (Max-1).

Since you'll always check 2 items in your list at the most then incrementing will be of O(1)

Just don't try doing other arithmentic with your shiny new counter :D




回答4:


My try:

we keep an aggregation on consecutive 1 or 0.

meaning 111000111 is <1,0> <3,1> <3,0> <3,1>

I can represent this with the following DS:

List of Node { digit : bool, counter: long}

1) if the first bulk is of 1's. it turns to bulk of 0`s and turn the very next 0 to 1.

we now check if we can aggregate bulks of 1's.

2) if the first bulk is of 0's, we make the first digit 1. and see if we can aggregate 1's.

example A:

meaning 111000111 is <1,0> <3,1> <3,0> <3,1>

reading: three 1 digits, three 0 digits, three 1 digits, one 0 digits

increment()

<1,0> <3,1> <2,0> <1,1> <3,0>

example B:

<1,0> <3,1> <1,0> <3,1>

increment()

<1,0> <3,1> <1,1> <3,0>

aggregation:

<1,0> <4,1> <3,0>

There will always be const number of changes (up to the right most 0 digit)

and turnning bulk of 1s is just toggeling the boolean member. which is constant



来源:https://stackoverflow.com/questions/15012113/increment-an-infinite-binary-counter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!