The uniq method of the JavaScript Array adds a prototype method to the local object of the Array. It is used to delete repeated entries in the Array entries (multiple entries may exist ), the returned value is a new array containing the deleted duplicate entries.
Formal Description:
Input
Array (size = N)
Output
Array1 = a subset of Array without repeated order preserving,
Non-repetition means that, for any a, B belongs to Array1,! = B
Ordering means that if the subscript of a in Array is smaller than that of B in Array, the subscript of a in Array1 is smaller than that of B in Array.
Array2 = Array-Array1, ordering
Realazy provides a new solution with a clear idea: traverse each element sequentially. If the value of this element has already been accessed, add Array2; otherwise, add Array1. The method used to determine whether the value of the current element has been accessed is to traverse all elements that have been accessed in sequence.
The complexity of this algorithm is about O (N ^ 2 ).
I have made some improvements in his algorithm framework. The key is how to determine whether the value of the current element has been accessed during the traversal process. A simple "Bucket" algorithm can be used when the original array value is a positive integer and the range = max value-min value is not very large.
Prepare a boolean array B with a length of range. The value of initialization is false. For each value in the original array, if B [value] = true, it indicates that this value has been accessed and put into Array2; otherwise, if it is put into Array1, B [value] = true.
This is obviously an O (N) algorithm. The cost is extra space complexity range, and the value range of the original array must be a positive integer.
It is not difficult to generalize to the case where the value field is an integer. In fact, you only need to evaluate the bucket value-min (Array) to convert it to a positive integer.
To avoid space waste caused by a large range, the hash algorithm is improved based on the "Bucket" algorithm. Specifically, the linear co-exclusive hashing method is used. The purpose is to compress the value range to a controllable small continuous positive integer subset, and ensure that the probability of the same image corresponding to different original images is as small as possible, in other words, load balancing should be performed between buckets as much as possible.
For example, this is a real-number hash function:
Key = hashFun (value) = Math. floor (value) * 37% 91
This is still the O (N) algorithm (obviously O (N) is the lower bound to the complexity of all uniq algorithms). The advantage is that it can control the space overhead and adapt to non-integer fields, you only need to design the corresponding hash function.
The following describes how to implement the bucket Algorithm:
Var resultArr = [],
ReturnArr = [],
OrigLen = this. length,
ResultLen;
Var maxv = this [0], minv = this [0];
For (var I = 1; I If (this [I]> maxv) maxv = this [I];
Else if (this [I] }
Var blen = maxv-minv + 1;
Var B = new Array (blen );
For (var I = 0; I For (var I = 0; I If (B [this [I]-minv]) {
ReturnArr. push (this [I]);
} Else {
ResultArr. push (this [I]);
B [this [I]-minv] = true;
}
}
ResultLen = resultArr. length;
This. length = resultLen;
For (var I = 0; I This [I] = resultArr [I];
}
Return returnArr;
The implementation of the hash algorithm is as follows:
Var shuffler = 37
Var beta = 0.007;
Var origLen = this. length
Var bucketSize = Math. ceil (origLen * beta );
Var hashSet = new Array (bucketSize );
Var hashFun = function (value ){
Var key = (Math. floor (value) * shuffler) % bucketSize;
Return key;
}
// Init hashSet
For (var I = 0; I //
Var ret = [], self = [];
Var key, value;
Var bucket, openLen;
Var everConflict;
For (var I = 0; I Value = this [I];
Key = hashFun (value );
Bucket = hashSet [key];
OpenLen = bucket. length; // if (openLen> 1) return;
EverConflict = false;
For (var j = 0; j If (bucket [j] = value ){
Ret. push (value );
EverConflict = true;
Break;
}
}
If (! EverConflict ){
Bucket. push (value );
Self. push (value );
}
}
SelfLen = self. length;
This. length = selfLen;
For (I = 0; I This [I] = self [I];
}
// Compute average bucket size
Var lens = [], sum = 0;
For (var I = 0; I Average = sum/hashSet. length; // watch lens, average
Return ret;
Use k * 10000 0 ~ K * 100 random integer test calculation time (MS)
K 1 2 3 4 5
Realazy 240 693 1399 2301 3807
Bucket 55 101 141 219 293
Hash 214 411 654 844 1083
The test framework draws on the http://realazy.org/lab/uniq.html
Test environment: Firefox2.0.0.6/Ubuntu7.10/2.66GHzP4/1024 MBDDR
The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion;
products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the
content of the page makes you feel confusing, please write us an email, we will handle the problem
within 5 days after receiving your email.
If you find any instances of plagiarism from the community, please send an email to:
info-contact@alibabacloud.com
and provide relevant evidence. A staff member will contact you within 5 working days.