Wir erhalten einen Strom von paarweise unterschiedlichen Zahlen aus der Menge .
Wie kann ich die fehlende Zahl mit einem Algorithmus ermitteln, der den Stream einmal liest und nur einen Speicher von Bits verwendet?
Wir erhalten einen Strom von paarweise unterschiedlichen Zahlen aus der Menge .
Wie kann ich die fehlende Zahl mit einem Algorithmus ermitteln, der den Stream einmal liest und nur einen Speicher von Bits verwendet?
Antworten:
Sie wissen , dass und weil konnte in codierter werdenBits dies getan werden kannSpeicher und in einem Weg (nur finden, dies fehlt Zahl).
Aber dieses Problem könnte im allgemeinen Fall (für die Konstante ) gelöst werden : Wir haben k fehlende Zahlen, finden Sie alle heraus. In diesem Fall, anstatt nur die Summe von y i zu berechnen, berechnen Sie die Summe der j'sten Potenz von x i für alle 1 ≤ j ≤ k (ich nahm an, dass x i fehlende Zahlen und y i eingegebene Zahlen sind):
Denken Sie daran , dass Sie berechnen können , einfach, weil S 1 = S - ∑ y i , S 2 = ∑ i 2 - ∑ y 2 i , ...
Um nun fehlende Zahlen zu finden, müssen Sie lösen , um alle x i zu finden .
Sie können berechnen:
, P 2 = ≤ x i ≤ x j , ..., P k = ≤ x i ( 2 ) .
Beachten Sie dazu , dass , P 2 = S 2 1 - S 2 , ...
Aber ist Koeffizienten von P = ( x - x 1 ) ⋅ ( x - x 2 ) ⋯ ( x - x k ) aber P berücksichtigt werden kann eindeutig, so dass Sie fehlende Zahlen finden.
Das sind nicht meine Gedanken; lies das .
Aus dem obigen Kommentar:
Before processing the stream, allocate bits, in which you write ( is the binary representation of and is pointwise exclusive-or). Naively, this takes time.
Berechnen Sie nach der Verarbeitung des Streams immer dann, wenn man eine Zahl liest , x : = x ⊕ b i n ( j ) . Lassen Sie k die Zahlen von seinem { 1 , . . . n } , das nicht im Stream enthalten ist. Nachdem wir den gesamten Strom gelesen haben, haben wir x = ( n ⨁ i = 1 b i n ( i ) ) ⊕ ( ⨁ i ≠ k b das gewünschte Ergebnis ergibt.
Daher haben wir verwendet und haben eine Gesamtlaufzeit von O ( n ) .
HdM's solution works. I coded it in C++ to test it. I can't limit the value
to bits, but I'm sure you can easily show how only that number of bits is actually set.
For those that want pseudo code, using a simple operation with exclusive or ():
Hand-wavey proof: A never requires more bits than its input, so it follows that no intermediate result in the above requires more than the maximum bits of the input (so bits). is commutative, and , thus if you expand the above and pair off all data present in the stream you'll be left only with a single un-matched value, the missing number.
#include <iostream>
#include <vector>
#include <cstdlib>
#include <algorithm>
using namespace std;
void find_missing( int const * stream, int len );
int main( int argc, char ** argv )
{
if( argc < 2 )
{
cerr << "Syntax: " << argv[0] << " N" << endl;
return 1;
}
int n = atoi( argv[1] );
//construct sequence
vector<int> seq;
for( int i=1; i <= n; ++i )
seq.push_back( i );
//remove a number and remember it
srand( unsigned(time(0)) );
int remove = (rand() % n) + 1;
seq.erase( seq.begin() + (remove - 1) );
cout << "Removed: " << remove << endl;
//give the stream a random order
std::random_shuffle( seq.begin(), seq.end() );
find_missing( &seq[0], int(seq.size()) );
}
//HdM's solution
void find_missing( int const * stream, int len )
{
//create initial value of n sequence xor'ed (n == len+1)
int value = 0;
for( int i=0; i < (len+1); ++i )
value = value ^ (i+1);
//xor all items in stream
for( int i=0; i < len; ++i, ++stream )
value = value ^ *stream;
//what's left is the missing number
cout << "Found: " << value << endl;
}