English 中文(简体)
限制之间出现阵列要素数目的快速途径
原标题:Fastest way of putting array elements number of occurrences between limits

For example...

  1. I have an array of integers which is initialized by random values between 1 and 1000
  2. Array has 1M elements (it will probably have much more, but this is only the example)
  3. Number of each element s occurrences must be between 10 and 1010

如何最快地调整这一阿雷拉元件,使之达到上述标准?

我的第一个解决办法是,如果最大数量的出现接近于阵列,那么就过于缓慢。 Length (1M)/ ValuesSpan(1000)

我尝试过这样的东西(这只是为了调和可能发生的情况,下限的解决办法几乎相同):

Int64[] DistinctArrayElements = distinctArrayElements;
Dictionary<Int64, Int32> occurrences = new Dictionary<Int64, Int32>();

foreach (Int64 DistinctElement in DistinctArrayElements)
{
    occurrences.Add(DistinctElement, 0);
}

foreach (Int64 ArrayElement in Arr)
{
    occurrences[ArrayElement] += 1;
}
//I know this initialization can be done more nicely, so don t bother with this.

for (int j = 0; j < Arr.Length; j++)
{
    if (occurrences[Arr[j]] > upperNoOfOccurrences)
    {
        for (int i = 0; i < Arr.Length; i++)        
        {
            if (occurrences[Arr[i]] < upperNoOfOccurrences)
            {
                Arr[j] = Arr[i];
                occurrences[Arr[i]] += 1;
                occurrences[Arr[j]] -= 1;
            }
        }
    }
}
问题回答

从你想要做的事情来看,我不会产生真正的意义。 然而,处理阵列似乎是一种浪费。 你们都可以只看一ing(在你摆脱“自由”的独特价值时,我们几乎没有前进的轨道)。 下面肯定不是我所写的最恶法,但我认为这为你的问题提供了解决办法。

HashSet<long> forbidden = new HashSet<long>(); // maximum size of 1000, contains values that exceeded the limit
Queue<long> remaining = new Queue<long>(1000); // stores found unique values within the limit in a queue, that will be used if we bounce into the limit
Dictionary<long, int> frequencies = new Dictionary<long, int>(1000);
int lastPeekIndex = 0;
for (int i = 0; i < Arr.Length; i++) {
  if (!frequencies.ContainsKey(Arr[i])) {
    frequencies[Arr[i]] = 0;
    remaining.Add(Arr[i]);
  }

  if (frequencies[Arr[i]] == upperLimit) {
    if (!forbidden.Contains(Arr[i])) forbidden.Add(Arr[i]);
    var next = Int64.MinValue;
    try {
      next = remaining.Dequeue();
      while (forbidden.Contains(next)) next = remaining.Dequeue();
    } catch (InvalidOperationException) { // Arrr! we have not yet observed enough unique values
      for (int j = Math.Max(i, lastPeekIndex) + 1; j < Arr.Length; j++)
        if (!frequencies.ContainsKey(Arr[j])) {
          frequencies[Arr[j]] = 0;
          next = Arr[j];
          lastPeekIndex = j;
        }
    }
    Arr[i] = next;
    frequencies[next]++;
    if (frequencies[next] < upperLimit) remaining.Enqueue(next);
  } else frequencies[Arr[i]]++;
}

请注意,这并不阻止下限,因为你没有这样做。 我认为,你们必须注意在第二次通行证中往往不够的价值观。 在第一次通行证之后,你可以把他们放在另一个位置上,然后再次对阵列进行敲响,直到被点空为止(或许在第二张通行证中,至少需要一个完全的隔热)。

我要说一下你的话语,这样,人数似乎较少的人就能够首先发言。 这样,你就不必每次寻找合适的人数,只是用较少的发生率来替代。 这里有一条假图,解释:

struct dict {
    key, value
}

linkedList<dict> occurrences;

initialize occurrences
sort it (smallest values first)

// start from the one with greatest number of occurrences
n = occurrences.last;

// keep going until occurrences of n is greater than upperNoOfOccurrences
while n.value.value > upperNoOfOccurrences and didn t reach first element
    repeat = true

    do:
        // required occurrences to subtract to be within the limit
        required = upperNoOfOccurrences - n.value.value

        // maximum occurrences we can add to the first
        maxAllowed = upperNoOfOccurrences - occurrences.first.value.value

        // if we can do that
        if required < maxAllowed:
            occurrences.first.value.value += required
            n.value.value -= required
            repeat = false
        else:    // n.value.value is still greater than upperNoOfOccurrences
            occurrences.first.value.value += maxAllowed 
            n.value.value -= maxAllowed 
            repeat = true
        end if

        // keep occurrences sorted
        newPos = occurrences.first.next
        while occurrences.first.value > newPos.value.value:
            newPos = newPos.next

        move occurrences.first before newPos
    while repeat
end while

now rebuild your array with occurrences. it will
be sorted  but it doesn t matter does it? ;)

这里采用一种简单而准确的方法,对符合你的标准的成套数字进行统一抽样。

  1. Let M = number of distinct values; N = number of array elements; L = lower limit on count of instances of each value; U = upper limit on count; D = U-L. For your example, M=1000, N=1000000, L=10, U=1010, and D=1000.
  2. Create array S, of size M*D. Set the first N entries of S to 1, and the rest to zero.
  3. Shuffle S via Fisher–Yates shuffle. (See links here)
  4. Create array T, of size M.
  5. For i up to M, set T[i] = L + S[iD] + S[iD+1] + ... + S[i*D+D-1].
  6. Create array V, of size N. Fill it with T[0] instances of the 0 th value and so forth, i.e. with T[i] instances of the i th value, for each i. Because S contained N 1 s, V will be filled completely and exactly.
  7. Shuffle V via Fisher–Yates shuffle. Then array V satisfies the original criteria.

请注意,步骤2-5为O(MD),而6至7为O(N+M),后者与可以达到的正好相同,因为MD在你的问题陈述中是O(N)。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签