struct Event
{
int ObjectID{};
EnumOp Op{};
high_resolution_clock::time_point WakeUpTime{};
int TargetID{};
constexpr bool operator>(const Event& rhs) const
{
return WakeUpTime > rhs.WakeUpTime;
}
};
priority_queue<Event, vector<Event>, greater<Event>> TimerQueue;
The default sorting method for priority queues is less. It actually sorts in ascending order, but is top returning the last element? Or is it sorting in descending order, despite being less, so top returns the first element?
top returns the highest ranked element (i.e, the one with the highest priority). And yes, by default it uses operator <
Note that the elements in the underlying container are not sorted. They are ordered, but not in ascending (or descending) order.
Related
I have two 2D-arrays; both of which contain a timestamp and a float-value. Array1 contains hundreds of timestamp-value pairs, while Array2 will generally only contain ~10 timestamp-value pairs.
I am trying to compare Array1 with Array2, and only want to keep Array1's timestamp-value pairings for the timestamps that are closest to the timestamps in Array2.
Array1 = {[59.696, 2020-12-30T00:00:00.000Z],
[61.381, 2020-12-30T00:15:00.000Z],
[59.25, 2020-12-30T00:30:00.000Z],
[57.313, 2020-12-30T00:45:00.000Z],...}
Array2 = {[78.210, 2020-12-30T00:06:00.000Z],
[116.32, 2020-12-30T00:39:00.000Z],...}
So in these Array examples above, I would want Array1 to be filtered down to:
Array1 = {[59.696, 2020-12-30T00:00:00.000Z],
[57.313, 2020-12-30T00:45:00.000Z],...}
because those timestamps are the closest match for timestamps in Array2.
I have tried implementing the suggested code from Find matches for two columns on two sheets google script but can't get it to work, and I can't otherwise find a neat solution for the timestamp matching.
Any help is much appreciated. Let me know if I need to edit or add to my question with more information.
The goal
Given two arrays:
Array1 = [
[59.696, "2020-12-30T00:00:00.000Z"],
[61.381, "2020-12-30T00:15:00.000Z"],
[59.25, "2020-12-30T00:30:00.000Z"],
[57.313, "2020-12-30T00:45:00.000Z"]
]
Array2 = [
[78.210, "2020-12-30T00:06:00.000Z"],
[116.32, "2020-12-30T00:39:00.000Z"]
]
The goal is for each item in Array2 to be matched with the closest date in Array1. So the resultant array of the above example would be 2 items. If Array2 had 100 items and Array1 had 1000, the resultant array would be of 100 items.
I am assuming that each item in Array1 can only be used once.
I am also assuming that the first item in the array, the float value, is to be ignored in the calculation, but kept together with the date and be included in the output.
The script
function filterClosestTimes(array1, array2) {
// Initializing "maps" to keep track of the differences
// closest, will contain the final pairs used
// differences, is used to decide which pair gets used
// positions used, is so that the same pair in array 1
// doesn't get used twice.
closest = []
differences = []
positionsUsed = []
// For each member of array2
array2.forEach((pair, i) => {
// Initializing a date object
targetDate = new Date(pair[1])
// Initializing the position of the current index in the
// tracking arrays.
closest.push(null)
differences.push(Infinity)
positionsUsed.push(null)
// Going through each member of array 1
array1.forEach((subpair, j) => {
// First checking if the position has already been used
if (positionsUsed.includes(j)) return
//initializing date
dateToTest= new Date(subpair[1])
// checking difference between the currently testing date
// of array 2
difference = Math.abs(targetDate - dateToTest)
// Checking if it is the date with the smallest difference
// if so, setting the position in the tracking arrays.
// These values will likely be overwritten many times until
// the date with the least difference is found.
if (differences[i] > difference) {
differences[i] = difference
closest[i] = subpair
positionsUsed[i] = j
}
})
})
return closest
}
function test(){
Logger.log(filterClosestTimes(Array1, Array2))
}
Running test returns:
[["59.696, 2020-12-30T00:00:00.000Z"], ["57.313, 2020-12-30T00:45:00.000Z"]]
Note
This algorithm, seeing as it involves checking every element of one array with almost every one in another array, can get slow. Though if you are only dealing with hundreds of values and comparing with ~10 in your Array2 then it will be fine. Just be aware that this approach has O(n^2) time complexity. Which will mean that as the number of comparisons go up, the time needed to complete the operation increases exponentially. If you try to compare tens of thousands with tens of thousands, then there will be a noticeable wait!
References
JS Date object
Time Complexity
I want to build a Scrabble Cheater which stores Strings in an array of linked lists. In a perfect scenario each linked list would only have words with the same permutations of letters (like POOL and LOOP for example). The user would put a String in there like OLOP and the linked list would be printed out.
I want the task to be explicitly solved using hashing.
I have built a stringHashFunction() for that (Java code):
public int stringHashFunction(String wordToHash) {
int hashKeyValue = 7;
//toLowerCase and sort letters in alphabetical order
wordToHash = normalize(wordToHash);
for(int i = 0; i < wordToHash.length(); i++) {
int charCode = wordToHash.charAt(i) - 96;
//calculate the hash key using the 26 letters
hashKeyValue = (hashKeyValue * 26 + charCode) % hashTable.length;
}
return hashKeyValue;
}
Does it look like an OK-hash-function? I realize that it's far from a perfect hash but how could I improve that?
My code overall works but I have the following statistics for now:
Number of buckets: 24043
All items: 24043
The biggest bucket counts: 11 items.
There are: 10264 empty buckets
On average there are 1.7449016619493432 per bucket.
Is it possible to avoid the collisions so that I only have buckets (linked lists) with the same permutations? I think if you have a whole dictionary in there it might be useful to have that so that you don't have to run an isPermutation() method on each bucket every time you want to get some possible permutations on your String.
(my code is written in Java but the question is agnostic; I'm just looking for an algorithm idea)
So here's the problem: I made a method that simply finds the median of a data set (given in the form of an array). Here's the implementation:
public static double getMedian(int[] numset) {
ArrayList<Integer> anumset = new ArrayList<Integer>();
for(int num : numset) {
anumset.add(num);
}
anumset.sort(null);
if(anumset.size() % 2 == 0) {
return anumset.get(anumset.size() / 2);
} else {
return (anumset.get(anumset.size() / 2)
+ anumset.get((anumset.size() / 2) + 1)) / 2;
}
}
A teacher in the school that I go to then challenged me to write a method to find the median again, but without using any data structures. This includes anything that can hold more than one value, so that includes Strings, any forms of arrays, etc. I spent a long while trying to even conceive of an idea, and I was stumped. Any ideas?
The usual algorithm for the task is Hoare's Select algorithm. This is pretty much like a quicksort, except that in quicksort you recursively sort both halves after partitioning, but for select you only do a recursive call in the partition that contains the item of interest.
For example, let's consider an input like this in which we're going to find the fourth element:
[ 7, 1, 17, 21, 3, 12, 0, 5 ]
We'll arbitrarily use the first element (7) as our pivot. We initially split it like (with the pivot marked with a *:
[ 1, 3, 0, 5, ] *7, [ 17, 21, 12]
We're looking for the fourth element, and 7 is the fifth element, so we then partition (only) the left side. We'll again use the first element as our pivot, giving (using { and } to mark the part of the input we're now just ignoring).
[ 0 ] 1 [ 3, 5 ] { 7, 17, 21, 12 }
1 has ended up as the second element, so we need to partition the items to its right (3 and 5):
{0, 1} 3 [5] {7, 17, 21, 12}
Using 3 as the pivot element, we end up with nothing to the left, and 5 to the right. 3 is the third element, so we need to look to its right. That's only one element, so that (5) is our median.
By ignoring the unused side, this reduces the complexity from O(n log n) for sorting to only O(N) [though I'm abusing the notation a bit--in this case we're dealing with expected behavior, not worst case, as big-O normally does].
There's also a median of medians algorithm if you want to assure good behavior (at the expense of being somewhat slower on average).
This gives guaranteed O(N) complexity.
Sort the array in place. Take the element in the middle of the array as you're already doing. No additional storage needed.
That'll take n log n time or so in Java. Best possible time is linear (you've got to inspect every element at least once to ensure you get the right answer). For pedagogical purposes, the additional complexity reduction isn't worthwhile.
If you can't modify the array in place, you have to trade significant additional time complexity to avoid avoid using additional storage proportional to half the input's size. (If you're willing to accept approximations, that's not the case.)
Some not very efficient ideas:
For each value in the array, make a pass through the array counting the number of values lower than the current value. If that count is "half" the length of the array, you have the median. O(n^2) (Requires some thought to figure out how to handle duplicates of the median value.)
You can improve the performance somewhat by keeping track of the min and max values so far. For example, if you've already determined that 50 is too high to be the median, then you can skip the counting pass through the array for every value that's greater than or equal to 50. Similarly, if you've already determined that 25 is too low, you can skip the counting pass for every value that's less than or equal to 25.
In C++:
int Median(const std::vector<int> &values) {
assert(!values.empty());
const std::size_t half = values.size() / 2;
int min = *std::min_element(values.begin(), values.end());
int max = *std::max_element(values.begin(), values.end());
for (auto candidate : values) {
if (min <= candidate && candidate <= max) {
const std::size_t count =
std::count_if(values.begin(), values.end(), [&](int x)
{ return x < candidate; });
if (count == half) return candidate;
else if (count > half) max = candidate;
else min = candidate;
}
}
return min + (max - min) / 2;
}
Terrible performance, but it uses no data structures and does not modify the input array.
I have a problem to solve with Android, but it's really confusing.
Using the function below:
function accumulate(combiner, nullValue, list){
if(list.length == 0){
return nullValue;
}
var first = list.removeFirst();
return combiner(first, accumulate(combiner, nullValue, list));
}
Develop the function sumOfSquares which returns the sum of squares of a list (Example: 1² + 2² + 3²...)
sumOfSquares([1,2,3,4,5])
returns the number 55.
In this case, the function accumulate must be used. The variable "combiner" is a "pointer to a function". The implementation of the function "combiner" is part of the solution.
I have no problem with the basics, doing the sum of squares, etc, but the part "pointer to a function" really confused me.
If anyone can tell me which is the way to get to the answer, I will be thankful :)
I have done until the code below:
public class MainActivity extends Activity{
protected void onCreate(...){
....
List<Integer> list = new ArrayList<Integer>();
//Fill the list with values
long value = accumulate(sumOfSquares(list), 0, list);
//Show the value
}
private int sumOfSquares(List<Integer> list){
int sum = 0;
for(int i = 0; i < list.size(); i++){
sum += Math.pow(list.get(i), 2);
}
return sum;
}
private long accumulate(int combiner, long nullValue, List<Integer> list){
if(list.size() == 0){
return nullValue;
}
int first = list.get(0);
list.remove(0);
return combiner(first, accumulate(combiner, nullValue, list));
}
private long combiner(int first, int rest){
return first + rest;
}
}
In some languages, the notion of a pointer to a function makes sense, and you could write the code pretty much as you've given it in the example. Not in Java, though, which is what underlies Android. (Android is a bit of a weird choice for this, by the way...)
What you want to do in Java (without giving you the whole solution) is to define a
private int combiner(int first, int rest);
method that takes the first element of the list and the solution to the smaller problem defined by the rest of the list, and produces the answer from these two bits. In other words, if first is the first element, and rest is the sum of the squares of everything except the first element, what is the sum of the squares of the whole list (in terms of first and rest)?
Now your accumulate method does almost exactly what you've written out. It just removes the first element, recursively calls itself on the rest of the list, and returns the value of combining the first element with the result of the recursive call.
The nullValue is there to give you the sum of the squares of an empty list.
If you want to look up more of the details of the theory, you're basically doing functional programming but in an imperative language :)
Checking this example (API example at the end), I want to ask a few questions.
1) In the example we are supplying matrix a with non zero elements.What is the real size of the matrix though?And these are the elements of the matrix or the positions that contain non zero elements?
2) Can I use at the calculations (use in a function like culaSparseSetDcooData) a matrix A which will contain zero and non zero elements?
If I want to create a sample matrix just to test ,should I have to create a matrix with zero elements,then fill it with some elements and then?
Regarding 1) Interestingly, the size of the matrix in COO format is not explicitly specified: It consists of coordinates of the non-zero elements of the matrix. If you have a COO matrix with 1 non-zero element, then this could be
double a[1] = { 1.0 };
int colInd[1] = { 10 };
int rowInd[1] = { 20 };
and (as you can tell from the row/column indices) describe elements of a matrix that has at least size 11*21, or it could be
double a[1] = { 1.0 };
int colInd[1] = { 1000 };
int rowInd[1] = { 2000 };
and describe elements of a matrix that has at least size 1001*2001
However, in this example, it seems like this is a quadratic matrix, and n=8 seems to be the size. (Unfortunately, there seems to be no detailed documentation of the culaSparseSetDcooData function...)
Regarding 2) This is not entirely clear. If your question is whether the "non-zero" values may (in reality) have a value of 0.0, then I can say: Yes, this should be allowed. However, the example that you referred to already shows how to create a simple test matrix.