To design a API,
get(), it will return the random number, also the number should not duplicate, means it always be unique.
put(randomvalue), it will put back the generated random number from get(), if put back, get() function can reuse this number as output.
It has to be efficient, no too much resource is highly used.
Is there any way to implement this algorithm? It is not recommended to use hashmap, because if this API generate for billions of requests, saving the generated the random number still use too much space.
I could no work out this algorithm, please help give a clue, thanks in advance!
I cannot think of any solution without extra space. With space, one option could be to use TreeMap, firstly add all the elements in treeMap with as false. When element is accessed, mark as true. Similarly for put, change the value to false.
Code snippet below...
public class RandomNumber {
public static final int SIZE = 100000;
public static Random rand;
public static TreeMap<Integer, Boolean> treeMap;
public RandomNumber() {
rand = new Random();
treeMap = new TreeMap<>();
}
static public int getRandom() {
while (true) {
int random = rand.nextInt(SIZE);
if (!treeMap.get(random)) {
treeMap.put(random, true);
return random;
}
}
}
static public void putRandom(int number) {
treeMap.put(number, false);
}
}
Related
I'm upgrating from IText 5 to IText 7. The code below is from version 5 which has a method to get the actual number of lines written. How can I accomplish the same using IText 7?
Paragraph p = new Paragraph(veryLongText, font);
ColumnText column1 = new ColumnText(writer.DirectContent);
column1.SetSimpleColumn(bottomX, bottomY, topX, 100);
column1.AddElement(p);
column1.Go(true);
noOfLines = column1.LinesWritten; <---- No of Lines
Layout mechanism in iText 7 is much more complex and feature-rich than mechanism in iText 5, and notion of written lines might be very much opinion-based in many complex layout cases. That's why the number of written lines is not maintained by the layout engine and is not available for query. However, it's very easy to extend your elements/renderers to support calculating the number of written lines. Here is how to do it. First, you need to override a Paragraph to aggregate the number of lines and ParagraphRenderer to provide the info of the lines written back to Paragraph:
private static class LineCountingParagraph extends Paragraph {
private int linesWritten = 0;
public LineCountingParagraph(String text) {
super(text);
}
public void addWrittenLines(int toAdd) {
linesWritten += toAdd;
}
public int getNumberOfWrittenLines() {
return linesWritten;
}
#Override
protected IRenderer makeNewRenderer() {
return new LineCountingParagraphRenderer(this);
}
}
private static class LineCountingParagraphRenderer extends ParagraphRenderer {
public LineCountingParagraphRenderer(LineCountingParagraph modelElement) {
super(modelElement);
}
#Override
public void drawChildren(DrawContext drawContext) {
((LineCountingParagraph)modelElement).addWrittenLines(lines.size());
super.drawChildren(drawContext);
}
#Override
public IRenderer getNextRenderer() {
return new LineCountingParagraphRenderer((LineCountingParagraph) modelElement);
}
}
Now, just use the customized classes instead of the standard ones and query the information after an element was added to a Document or Canvas:
LineCountingParagraph p = new LineCountingParagraph("text");
document.add(p);
System.out.println(p.getNumberOfWrittenLines());
Note that this mechanism also allows you to calculate the number of lines written that satisfy some condition. You can analyze elements in lines list.
I need your help.
If i want to sort a PriorityQeueu in java, with out connection to it's attributes - could i use the hashCode's Objects to compare?
This how i did it:
comp = new Comparator<Person>() {
#Override
public int compare(Person p1, Person p2) {
if(p1.hashCode() < p2.hashCode()) return 1;
if(p1.hashCode() == p2.hashCode()) return 0;
return -1;
}
};
collector = new PriorityQueue<Person>(comp);
It doesn't sound like a good approach.
Default hashCode() is typically implemented by converting the internal address of the object into an integer. So the order of objects will differ between application executions.
Also, 2 objects with the same set of attribute values will not return the same hashCode value unless you override the implementation. This actually breaks the expected contract of Comparable.
I am trying to find best way to compare Enums in Java 6.
Say, I have an ENUM of Ticket Types which can be associated with a Traveler. If there is a list of travelers, I would like to know the traveler with the highest class of travel.
I can iterate thru the list of travelers, create a Set of unique TicketTypes, Convert to List, Sort them, Return the last element as the highest. I would like to know if there is a better way to do this?
public enum TicketType {
ECONOMY_NON_REF(1,"Economy Class, Non-Refundable"),
ECONOMY_REF(2,"Economy Full Fare Refundable"),
BUSINESS(3,"Business Class"),
FIRST_CLASS(4,"First Class, Top of the world");
private String code;
private String description;
}
public class Traveler {
private TicketType ticketType;
public Traveler(TicketType ticketType) {
this.ticketType = ticketType;
}
}
#Test
public testCompareEnums{
List<Traveler> travelersGroup1 = new ArrayList<Travelers>();
travelersGroup1.add(new Traveler(TicketType.ECONOMY_REF));
travelersGroup1.add(new Traveler(TicketType.BUSINESS));
travelersGroup1.add(new Traveler(TicketType.ECONOMY_REF));
travelersGroup1.add(new Traveler(TicketType.ECONOMY_NON_REF));
//What is the best way to find the highest class passenger in travelersGroup1.
assertEquals(TicketType.BUSINESS, getHighestClassTravler(travelersGroup1));
List<Traveler> travelersGroup2 = new ArrayList<Travelers>();
travelersGroup2.add(new Traveler(TicketType.ECONOMY_REF));
travelersGroup2.add(new Traveler(TicketType.ECONOMY_NON_REF));
travelersGroup2.add(new Traveler(TicketType.ECONOMY_REF));
travelersGroup2.add(new Traveler(TicketType.ECONOMY_NON_REF));
assertEquals(TicketType.ECONOMY_REF, getHighestClassTravler(travelersGroup2));
}
private CredentialType getHighestClassTraveler(List travelers){
Set uniqueTicketTypeSet = new HashSet();
for (Traveler t: travelers) {
uniqueTicketTypeSet.add(t.getTicketType());
}
List<TicketType> uniqueTicketTypes = new ArrayList<TicketType>(uniqueTicketTypeSet);
Collections.sort(uniqueTicketTypes);
return uniqueTicketTypes.get(uniqueTicketTypes.size()-1);
}
There's a lot of problems with the code that you posted (it won't compile without fixing a lot of errors), but the easiest way is to make Traveler implement the Comparable interface, like so:
public int compareTo(Traveler other) {
return this.getTicketType().compareTo(other.getTicketType());
}
Then to find the the Traveler with the highest TicketType, you can simply do:
Collections.max(travelers);
Hard question to understand perhaps, but let me explain. I have a List of Channel-objects, that all have a ChannelId property (int). I also have a different List (int) - SelectedChannelIds, that contains a subset of the ChannelId-s.
I want to select (through LINQ?) all the Channel-objects that has a ChannelId-property matching one in the second List.
in other words, I have the following structure:
public class Lists
{
public List<Channel> AllChannels = ChannelController.GetAllChannels();
public List<int> SelectedChannelIds = ChannelController.GetSelectedChannels();
public List<Channel> SelectedChannels; // = ?????
}
public class Channel
{
// ...
public int ChannelId { get; set; }
// ...
}
Any ideas on what that LINQ query would look like? Or is there a more effective way? I'm coding for the Windows Phone 7, fyi.
You can use List.Contains in a Where clause:
public Lists()
{
SelectedChannels = AllChannels
.Where(channel => SelectedChannelIds.Contains(channel.ChannelId))
.ToList();
}
Note that it would be more efficient if you used a HashSet<int> instead of a List<int> for the SelectedChannelIds. Changing to a HashSet will improve the performance from O(n2) to O(n), though if your list is always quite small this may not be a significant issue.
SelectedChannels = new List<Channel>(AllChannels.Where(c => SelectedChannelIds.Contains(c.ChannelId)));
I have to implement a set ADT for a pair of strings. The interface I want is (in Java):
public interface StringSet {
void add(String a, String b);
boolean contains(String a, String b);
void remove(String a, String b);
}
The data access pattern has the following properties:
The contains operation is far more frequent that the add and remove ones.
More often that not, contains returns true i.e. the search is successful
A simple implementation I can think of is to use a two-level hashtable, i.e. HashMap<String, HashMap<String, Boolean>>. But this datastructure makes no use of the two peculiarities of the access pattern. I am wondering if there is something more efficient than the hashtable, maybe by leveraging the access pattern peculiarities.
Personally, I would design this in terms of a standard Set<> interface:
public class StringPair {
public StringPair(String a, String b) {
a_ = a;
b_ = b;
hash_ = (a_ + b_).hashCode();
}
public boolean equals(StringPair pair) {
return (a_.equals(pair.a_) && b_.equals(pair.b_));
}
#Override
public boolean equals(Object obj) {
if (obj instanceof StringPair) {
return equals((StringPair) obj);
}
return false;
}
#Override
public int hashCode() {
return hash_;
}
private String a_;
private String b_;
private int hash_;
}
public class StringSetImpl implements StringSet {
public StringSetImpl(SetFactory factory) {
pair_set_ = factory.createSet<StringPair>();
}
// ...
private Set<StringPair> pair_set_ = null;
}
Then you could leave it up to the user of StringSetImpl to use the preferred Set type. If you are attempting to optimize access, though, it's hard to do better than a HashSet<> (at least with respect to runtime complexity), given that access is O(1), whereas tree-based sets have O(log N) access times.
That contains() usually returns true may make it worth considering a Bloom filter, although this would require that some number of false positives for contains() are allowed (don't know if that is the case).
Edit
To avoid the extra allocation, you can do something like this, which is similar to your two-level approach, except using a set rather than a map for the second level:
public class StringSetImpl implements StringSet {
public StringSetImpl() {
elements_ = new HashMap<String, Set<String>>();
}
public boolean contains(String a, String b) {
if (!elements_.containsKey(a)) {
return false;
}
Set<String> set = elements_.get(a);
if (set == null) {
return false;
}
return set.contains(b);
}
public void add(String a, String b) {
if (!elements_.containsKey(a) || elements_.get(a) == null) {
elements_.put(a, new HashSet<String>());
}
elements_.get(a).add(b);
}
public void remove(String a, String b) {
if (!elements_.containsKey(a)) {
return;
}
HashSet<String> set = elements_.get(a);
if (set == null) {
elements_.remove(a);
return a;
}
set.remove(b);
if (set.empty()) {
elements_.remove(a);
}
}
private Map<String, Set<String>> elements_ = null;
}
Since it's 4:20 AM where I'm located, the above is definitely not my best work (too tired to refresh myself on the treatment of null by these different collections types), but it sketches the approach.
Do not use normal trees (most standard library data structures) for this. There is one simple assumption, which will hurt you in this case:
The normal O(log(n)) calculation of operations on trees assume that comparisons are in O(1). This is true for integers and most other keys, but not for strings. In case of strings each comparison is on O(k) where k is the length of the string. This makes all operations dependent on the length, which will most likely hurt you if you need to be fast and is easily overlooked.
Especially if you most often return true there will be k comparisons for each string at each level, so with this access pattern you will experience the full drawback of strings in trees.
Your access pattern is easily handled by a Trie. Testing if a string is contained is in O(k) worst case (not average case as in a hash map). Adding a string is is also in O(k). Since you are storing two strings I would suggest, you don't index your trie by characters, but rather by some larger type, so you can add two special index values. One value for the end of the first string, and one value for the end of both strings.
In your case using these two extra symbols would also allow for simple removal: Just delete the final node containing the end symbol and your string will not be found anymore. You will waste some memory, because you still have the strings in your structure that have been deleted. In case this is a problem you could keep track of the number of deleted strings and rebuild your trie in case this get's to bad.
P.s. A trie can be thought of as a combination of a tree and several hashtables, so this gives you the best of both data structures.
I'd second the approach of Michael Aaron Safyan to use a StringPair type. Perhaps with a more specific name, or as a generic tuple type: Tuple<A,B> instantiated to Tuple<String,String>. But I would strongly suggest to use one of the provided set implementations, either a HashSet or a TreeSet.
Red-Black Tree implementation of the set would be a good option. C++ STL is implemented in Red-Black Tree