I am working with daily stock price time series.
Each day i need to store 4 types of prices (open, high, low, close).
Whatever data structure I use I need to store it sin sequence (preferably a a date or integer as key to later retrieve any of those prices.
Length: variable can be from 2 to 200
I looked into arrays, ArrayLists, Vectors and Maps.
But I still have the problem that they holed pairs, and what I a looking for is to input 1 date or integer and assign to it 4 prices (string each).
Should I use an array and each element would be a class that has 5 members (date plus four kind of prices), then I create ArrayList, instantiate a new class and input is as an element?
Or is there a faster and less complicated way?
You can create a class lets say: price with four members:
open, high, low, close
Create a hash map with date as key and price class as value.
This way all the four members will have unique value for particular day.
All the value can be retrieved with
price.open and so on......
Related
I wondoner is it possible to implement priority query to solve following question: Suppose there is a school which needs to regulate its maximum current students due to the pandemic. For example, there are 4 lessons on some day, which are 9:00-11:00 with 50 students, 10:00-12:00 with 25 students, 14:00-16:00 with 60 students and 17:00-18:00 with 70 students. Then the maximum current students is 75 because when it is 10:00-11:00 there are 75 students in total taking lessons. My initial idea is to create two priority queue, one takes lesson start time as priority and another takes lesson end time. Can some one give any suggestions about this?
You can create an array where each index will represent an hour. And each element will be an integer representing how many MORE students are allowed in the school during this time.
For example array element with index 0 - represents 00:00, 22 - 23:00.
Then the array for your example will look like that:
[0(0:00),0,0,0,0,0,0,0,0,50(9:00),25(10:00),-50(11:00),-25(12:00),0,60(14:00),0,-60(16:00),70(17:00),-70(18:00),0,0,0,0,0]
And then when you need to know the number of students allowed at particular hour, you need to simply sum the array element up to the particular HOUR(index).
For example for 11:00 it will be 0+0+0+0+0+0+0+0+0+50+25=75.
Or when you insert the elements, you can as well update the rest of the array, to calculate the exact capacity for each hour. Then you don't have to calculate sum every time you need to know the number of allowed students. Your data structure will already content precalculated the values.
The array would look like that:
[0(0:00),0,0,0,0,0,0,0,0,50(9:00),75(10:00),25(11:00),0(12:00),0,60(14:00),0,0(16:00),70(17:00),0(18:00),0,0,0,0,0]
This is a trade of to make between slow selects vs slow inserts.
I am trying to write Java code for the following problem.But I am not able to find out a optimized way to solve this .
I have an array list of time and consumption of coffee as follows. I want to calculate the consumption of coffee every hours and if there is no consumption for a particular hour the next hours first entry will be the total consumption for that hour.
For Example :
I have the following array list
Time consumption of coffee
2:15 5 cups
2:30 6 cups
2:45 7 cups
3:05 2 cups
3:45 6 cups
5:05 1 cups
5:30 2 cups
7:15 1 cup
so I want to calculate what is the total consumption for hour 2 which will be in that case 18 cups from 2:00 to 3:00 .again for 3:00 to 4:00 it will be 8 cups. As there is no entry from 4:00 to 5:00 amount of consumption in that case should be amount of coffee consumed at 5:05 which is 1 cup.I want my result till 7 o'clock. As we don't have anything at 6:00 -7 :00 then it will be 1 cup which was value at 7:15.
So I want a final result of total consumption from 2:00 to 7:00 distributed every hour as array list as following object
obj1 = T<2:00,3:00,18>
obj2 = T<3:00,4:00,8>
obj3 = T<4:00,5:00,1>
obj4 = T<5:00,6:00,3>
obj5 = T<6:00,7:00,1>
finalList = <obj1,obj2,obj3,obj4,obj5>
I am not able to get how to chop the list in hourly way and look at the next value as well.
You completely lost me as to the logic of filling an empty hour with first value from the next hour. But I'll give it a shot anyways.
My approach assumes your input data is in chronological order from earlier to later.
Define a CoffeeConsumption class with two members, LocalTime and Integer for your two values.
Create a Map, perhaps a SortedMap such as TreeMap. The key is of type Integer, and represents the hour of the day from 0 to 23. The value is of type Set, perhaps a SortedSet such as TreeSet to store your custom objects defined above.
For each of you custom objects, grab its LocalTime and call getHour. Use that hour number to find the matching key in the Map, retrieve the Set, and add your item.
To get totals, loop the Map, and loop each Set. To save the totals, create a new SortedMap with Integer as key for hour-of-day and Integer as value for the hour’s total number of cups consumed.
Note that there is no need to save explicitly the end-of-hour time as you showed in your Question. You can always calculate that value: call LocalTime::plusHours( 1 ).
To support that move-first-item-to-previous-hour-if-empty feature, follow the logic I just outlined in that hyphenated title. When adding a coffee object to the Map with no existing key yet put there for that hour, first subtract one from the hour and look in the Map for that subtracted number as key. If the subtracted key is not present in the Map, put it, create a fresh empty Set in which to deposit the coffee object that would otherwise have gone to its own hour. Caveat: This feature has a bad smell and suggests something is wrong with your design or the requirement is misunderstood.
For example I have the following file
B 01-02-2013 1233
B 03-02-2013 129
B 04-02-2013 13
the date is stored as a String from user input. The next number is a integer for "CaloriesBurnt"
I want to if given a start date and end date. CALCULATE TOTAL CALORIES BURNED between those two dates. So for example here I would want to total the calories from 01-02-2013 TO 04-02-2013. So i need to pull the calories for the dates inbetween that period. I Know I have to convert to date format and then perhaps use a HASP MAP? to order?? any help really is appreciated
The best data structure in that situation is a TreeMap. It maintains its keys sorted, and has methods returning a "submap" containing all the entries between two key values.
If each date is unique, you can use a TreeMap<Date, Record>. If not, then use a TreeMap<Date, List<Record>> (Record being the class used to hold all the elements of one line of your file).
Once you have the submap, you just need to iterate on all the values and sum their calories.
First of all I would parse the whole text file into objects. No matter how the date is. Each line in the text file could be something like this (of course with setters and getters and public/private and all this stuff ;):
class Entry {
Date date;
int calories;
}
Parse the text file and create a list of such objects. Then you could operate on this list. You can sort it (with a sorter-object written by you), you can search it or do what ever you want. Once you get rid of the actual text file and you have objects, it gets much easier. You can even use some third-party libraries to easily compute statistics (e.g. the average, max values or such things).
You might probably want to use a sorted collection like a SortedMap<Date, UserData> ( UserData would represent whatever data you want to store in the map), then use subMap(startDate, endDate + 1 day) to extract period. Note that endDate + 1 day is needed since the upper bound is exclusive.
Example:
SortedMap<Date, Integer> caloriesByDate = new TreeMap<>(); //we only store the calories
... //fill here
SimpleDateFormat f = new SimpleDateFormat("dd-MM-yyyy");
//get entries in the interval `[01-02-2013,03-02-2013]`.
caloriesByDate.subMap( f.parse("01-02-2013"), f.parse("04-02-2013") );
I'm new. I'm writing an app for a laser tag place where we've got kids of many ages coming to shoot beams at each other. We're making a highscore screen that'll display the best scores of the day, of the week, and of the month. The idea is that people will feel proud being on the list, and there'll also be prizes once a month.
I'm getting stuck at the whole filtering by date thing.
I basically modified the classic guestbook example to the point where I can add scores and customer info, and sort them by score.
Key guestbookKey = KeyFactory.createKey("Guestbook", guestbookName);
String fornavn = req.getParameter("fornavn");
Integer score = Integer.parseInt(req.getParameter("score"));
String email = req.getParameter("email");
String tlf = req.getParameter("tlf");
Date date = new Date();
Entity highscore = new Entity("Greeting", guestbookKey);
highscore.setProperty("date", date);
highscore.setProperty("fornavn", fornavn);
highscore.setProperty("score", score);
highscore.setProperty("email", email);
highscore.setProperty("tlf", tlf);
DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
datastore.put(highscore);
And in the jsp there's a query that grabs the overall top 5.
Query query = new Query("Highscore", highscoreKey).addSort("score", Query.SortDirection.DESCENDING);
List<Entity> greetings = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(5));
And there's a form that sends the user input to the .java. Any tips as far as how I should set up the dates? Saving week # and month # and querying based on that? Seems cumbersome.
From what I can tell, your "HighScore" kind is actually a "Score" kind that keeps track of all scores.
Instead of querying for the high score for the week/month, you're probably better off having a single HighScore entity (that's separate from normal "Score" entities) that you update whenever you enter a score. Every time a new score is entered, check if the high score should be updated.
You never need a fancy query, you just need to fetch the high score entity.
Or you might want a separate high score entity for each month/week etc so you can keep track of the history. In this case you may want to encode week or month into the entity key, so you can get the current week/month's HighScore easily.
There are 2 possible approaches for a requirement like yours where you want to show highscores for a day, week, month, etc:
1, First option is to use your current model where you are storing date and score. Since app engine allows inequality filter only on 1 property, you need to apply an inequality filter on date and then find the n highest number of scores. But since the result will be sorted first for the property with inequality filter and then for any additional property, you cannot do a fetch for only the first n entries to find the top n because the top scores need not be in continuous order. See this post to understand this better. So you will have to fetch all the scores for the date range and then do further sorting of the query result at your client to find the top n. This approach is ok if the total number of scores for a week or a month will not be too high compared to the value of n. If not, this is not a scalable option.
2, Second approach is to redesign your model such that sorting happens on scores so that for getting top n scores for a particular period, you need to fetch only the first n entries. This means the approach is suitable even if number of scores are very large. This then requires converting your date to be suitable for equality filtering like for each entry storing a month number, a week number and calendar year. Then for example if you want to find the top n scores in the 3rd month, then you can query for month=3, sort by scores descending and fetch the first n matching entries. Similarly you can query for a particular week using a week number.
This is very similar to another high-score SO question. I have copied/pasted my answer to it below. Approaching this solution using a database query may cause you to join the ranks of folks who complain about GAE. You will be using a custom index. Your query will likely average 10x miliseconds slower than needed per request. You will need to index thousands, perhaps millions of records. This costs you money -- perhaps lots of it both re: data storage (indices) and instances due to your high latency for what will likely be a highly-called handler function. Think different please. My copy/paste is not as specific to your setup, but it can be easily extended easily. I hope that it might prompt you to think about lower resource, lower cost alternative. As always...HTH. -stevep
Previous high score answer:
You may want to consider an alternate approach. This is a lot of index overhead which will cause your costs to be higher, the response time for the handler executing this function to operate an order of magnitude slower and you will have moments where the eventual consistency of index updates will affect maintenance of this data. If you have a busy site, you will surely not be happy with the latency and costs associated with this approach.
There are a number of alternate approaches. Your expected site transactions per second would affect which you choose. Here is a very simple alternative. Create an ndb entity with a TextProperty. Serialize the top scores entries using a string such as score_userid. Store them in the text field by joining them with a unique character. When a new score comes in, use get_by_id to retrieve this record (ndb automatically handles memcaching for you). Split it into an array. Split the last element of the array, and check against the new score. If it is less than the score, drop it, and append the new score_userid string to the array. Sort the array, join it, and put() the new TextProperty. If you want you could set up an end of the day cron to scan your scores for the day to check to see if your process was affected by the very small chance that two scores arrived at nearly the same time causing one to overwrite the other. HTH. -stevep
Previous SO high score answer link:
GAE datastore query with filter and sort using objectify
In Java is there any way to store time ranges as key in Hashmap? I have one HashMap and I store times time range. For example:
I enter 0-50 range as key and for that key I will store some other objects as value. Now when I say 10 I should be able to get the corresponding value for that key.
Any value between 0-50 should get that object.
Map map = new HashMap();
map.put(0-50,"some object")
map.put(51-100,"some other object")
now when I say map.get(10) it should be able to get the "some object". Please suggest how to do this?
I wouldn't use a map, instead I would try with a R-Tree. A R-tree is a tree structure created for indexing spatial data. It stores rectangles. It is often used to test if a point (coordinate) is lying within an other geometry. Those geometries are approximated by rectangles and those are stored in the tree.
To store a rectangle (or the information about it) you only need to save the lower left and upper right corner coordinates. In your case this would be the lower and upper bound of the time span. You can think of it, as if all y values of the coordinates were 0. Then you can query the tree with your time value.
And of course you would save the value at each leaf (time span/rectangle)
A simple search on google for r-tree java brought up some prominising results. Implementing your own R-tree isn't trivial, but it is not too complicated if you understood the principle of re-arranging the tree upon insertion/deletion. In your one dimensional case it might get even simpler.
Assumptions: Non-overlapping ranges.
You can store the starting point and ending point of the ranges in an TreeSet. The starting point and ending point are objects that store the starting time and ending time respectively, plus (a reference to) the object. You have to define comparison function, so that the objects are ordered by the time.
You can obtain the object by using floor() or ceiling() function of TreeSet.
Note that the ranges should NOT overlap, even at the endpoints (e.g. 3-6 and 6-10)
This will give you log complexity for range insertion and query.
If this is a non overlapping and equi distant range i.e. range split by say 50, you can solve this problem by maintaining hash for the max numbers like
50 - 'some object', 100 - 'some other object', etc..
if the input is 10, derive the immediate multiple of 50 and get the value for that key.
You can arrive at immediate multiple of 50
take mode on input say for the input 90 i.e. 90 % 50 = 40
compute diff of step 1 result with 50. i.e. 50 - 40 = 10
add step 2 result to input i.e. 90 + 10 = 100
You need to map the ranges to a single key, why dont you use something like a rangemanager object which returns for anyvalue between min and max the key 1 for example. alternativly you can put the someobject as a value for all keys between 1 and 50 using a for loop, but this would be a waste in my eyes.