The NavigableSet.lower(E) Javadoc says it returns the greatest element in this set strictly less than the given element, or null if there is no such element. Why is 1 the output here? Shouldn't it be 4?
NavigableSet original = new TreeSet();
original.add("1");
original.add("2");
original.add("3");
original.add("4");
original.add("10");
Object lower = original.lower("10");
System.out.println(lower);
Because the values are String(s) the Set is comparing by lexical order. Please, don't use Raw Types.
NavigableSet<Integer> original = new TreeSet<>();
original.add(1);
original.add(2);
original.add(3);
original.add(4);
original.add(10);
Object lower = original.lower(10);
System.out.println(lower);
Output is
4
thats because you are comparing Strings here, and not as assumed integers. So the actual order in the Set is : 1, 10, 2, 3, 4 !
Use the generics : NavigableSet<Integer> original = new TreeSet<>(); and add the values as integers :
original.add(1); and so on.
Related
I have a navigable set right now that stores Integers, how could I find the previous and next elements from a specific element? I'm not sure how to use an iterator if that's how you could find those elements.
Example:
NavigableSet<Integer> values = new TreeSet<>(List.of(1, 2, 3, 4, 5));
Lets say, given 3, I want to get hands on the 2 (previous) or the 4 (next).
Higher & Lower
Check the official documentation: NavigableSet
There are the methods
higher : Returns the least element in this set strictly greater than the given element, or null if there is no such element.
lower : Returns the greatest element in this set strictly less than the given element, or null if there is no such element.
Example:
TreeSet<Integer> values = new TreeSet<>(List.of(1, 2, 4));
// 3 is not contained
int lower1 = values.lower(3); // 2
int higher1 = values.higher(3); // 4
// 2 is contained
int lower2 = values.lower(2); // 1
int higher2 = values.higher(2); // 4
Ceiling & Floor
In case you are not looking for strictly greater or smaller, there are also
ceiling: Returns the least element in this set greater than or equal to the given element, or null if there is no such element.
floor: Returns the greatest element in this set less than or equal to the given element, or null if there is no such element.
Example:
TreeSet<Integer> values = new TreeSet<>(List.of(1, 2, 4));
// 3 is not contained
int lower1 = values.floor(3); // 2
int higher1 = values.ceiling(3); // 4
// 2 is contained
int lower2 = values.floor(2); // 2
int higher2 = values.ceiling(2); // 2
Notes
Be careful with the methods returning null if there is no such element. Especially if you auto-unbox to int. I.e.
int result = values.lower(1);
will crash with a NullPointerException. Stick to Integer instead of int if you want to check for existence first.
There are also many more methods that do similar things, such as headSet or tailSet, which you can also combine with an iterator afterwards.
In a NavigableSet taken You can use floor method to get the "previous" element:
Returns the greatest element in this set less than or equal to the given element, or null if there is no such element.
and the ceiling to get the "next" element:
Returns the least element in this set greater than or equal to the given element, or null if there is no such element.
This solution can be used for any kind of object.
By the way You are using integers that have always greater or lower than another integer if they are not equals you can use higher or lower:
(higher) Returns the least element in this set strictly greater than the given element, or null if there is no such element.
(lower) Returns the greatest element in this set strictly less than the given element, or null if there is no such element.
I've a non-empty array A consisting of N integers is given. The array contains an odd number of elements, and each element of the array can be paired with another element that has the same value, except for one element that is left unpaired.
For example, in array A such that below:
A[0] = 9 , A[1] = 3 , A[2] = 9 , A[3] = 3 , A[4] = 9 , A[5] = 7 , A[6] = 9
I need to write a functon that returns the value of the unpaired element.
One of my first native solutions was to create a hashmap structure with unique keys - N integers of given array and iterate through the array adding values if the key is already exists in the hashmap. After all the key that has only 1 at it's value field is the unpaired element.
I know that the hashcode of Integer is it's int unique value...
So I soposed that there will not be a duplicate keys of different Integers..So I supposed that there will not be a duplicate keys for different Integers..But for a big sets of data this solution does not work...I think this has something to do with load factor.
But I can't get on it. I don't need an alterntive solution, becouse I have it already, I just want to understand what's wrong with hashmap when we use a big sets of integer keys..
Here is my code and thank you very much!:
Map a = new HashMap();
for(int i=0;i<A.length;i++) {
if(a.containsKey(A[i])){
a.put(A[i], a.get(A[i])+1);
}else a.put(A[i], 1);
}
for (Integer i : a.keySet()) {
if(a.get(i)==1)
return i;
}
return -1;
enter image description here
I think this has something to do with load factor.
No, the problem is not in the HashMap, it's in the way you are using it.
Your solution is not complete because it assumes all the pairs are unique. i.e. it assumes there can be at most one pair of 9 (which is not true in the example you posted, which contains 2 pairs of 9).
Having multiple identical pairs will not necessarily result in a wrong answer, but what
if, for example, there are 3 9's, two of them are paired, but the 3rd is not? Your solution won't find it, since a.get(9) would return 3, but you check if it's equal to 1.
Instead of checking
if(a.get(i)==1)
you should check if it's odd
if(a.get(i)%2==1)
I'm currently learning in school but am unable to complete this part of the assignment.
An explanation with the use of for loops would be greatly appreciated.
The numbers should be added to the merged array in an alternating pattern: first from list 1, then from list 2, then list 1 again, etc. If a number in one of the arrays already appears in the merged array, then it should be ignored, and the program should alternate to the other list again. For example, if the first list begins 1 2 3 10, and the second begins 3 4 5 8, then the merged list would begin 1 3 2 4 5 10 8.
Because the number of elements in the merged array is unknown, its size should be set to the maximum possible number of elements it should contain, and after all elements which should form the merged array appear, any remaining unfilled spaces in the array should be 0. The first 0 encountered in the array should signal the end of the “actual” elements of the array, and therefore the 0s at the end of the array should not be printed by your program.
I propose to use a HashSet to remember which number you have already inserted into the array. For each number, you first check if the hash set already contains the number; if not, you add it to both the array and the set. For large inputs, this is much faster than checking the result array for each number. O(n*log(n)) or so (depending on how well the HashSet works for your input) instead of O(n^2).
#bubble
An example using a Set is very simple - however your teacher is asking for
an alternate list:
Integer[] one = new Integer[] {10,2,3,1};
Integer[] two = new Integer[] {3,8,5,4};
List<Integer> li_one = Arrays.asList(one); // First convert the arrays to a list
List<Integer> li_two = Arrays.asList(two);
Set<Integer> set = new HashSet<>();
set.addAll(li_one);
set.addAll(li_two);
System.out.println("The unique list is: " + set);
A HashSet was my first idea too, but the order of storing values depends
one hash values. The ... teacher likes to have alternating values which
I dont like to comment - because it is a really strange request.
Following code prints: merged list is: [1, 3, 2, 4, 5, 10, 8]
int[] one = new int[] {1,2,3,10};
int[] two = new int[] {3,4,5,8};
int one_len = one.length;
int two_len = two.length;
List<Integer> merged = new ArrayList<>();
int oneval,twoval;
for (int i = 0;i < one_len;i++)
{
oneval = one[i];
if (!merged.contains(oneval)) merged.add(oneval);
if (i < two_len)
{
twoval = two[i];
if (!merged.contains(twoval)) merged.add(twoval);
}
}
if (two_len > one_len)
{
for (int i = one_len; i < two_len;i++)
{
twoval = two[i];
if (!merged.contains(twoval)) merged.add(twoval);
}
}
System .out.println("merged list is: " + merged);
Say I have given array
int[] array = new int[50];
Then, say I assign 5 numbers to 5 locations
array[4] = 2
array[12] = 0
array[17] = 5
array[42] = 8
array[49] = 4
Is there a way I can loop through just the numbers I assigned without having a list that says "4, 12, 17, 42, 49" and get the output of "2, 0, 5, 8, 4"?
You can use the boxed type Integer which can be null.
Integer[] array = new Integer[50];
... assignment ...
for (Integer i : array)
if (i != null)
System.out.println(i);
Is there a way I can loop through just the numbers I assigned without having a list that says "4, 12, 17, 42, 49" and get the output of "2, 0, 5, 8, 4"?
No. you cannot do this with arrays. This will break the very purpose of array. You are actually expecting it to behave like a map.
Use proper map for this purpose. Here is an example
HashMap<Integer, Integer> map = new HashMap<>();
map.put(4, 2);
map.put(12, 0);
for(Integer value : map.values()) {
System.out.println(value);
}
Yes and no.
No, because you have to iterate over the whole array, unless you somehow store what values are set (what you don't want).
Yes, you can achieve to only get the output you want by setting some default values. For example initialize the array with Integer.MIN_VALUE and only handle values that are not equal to that value.
Consider a list of integers <1,5,10> (assume sorted in ascending fashion).
Given an integer, say, key = 6, is there a utility method that returns the smallest element after key (in this case it would be 10)?
NB: Looping through the elements in the list and comparing it with key is an obvious way to do it, but I'm just wondering if there exist a utility method to do the same thing :)
Have you considered Binary Search? Collections has a binarySearch method which you could use.
From the Collections binarySearch documentation:
Returns:
index of the search key, if
it is contained in the list;
otherwise, (-(insertion point) - 1).
The insertion point is defined as the
point at which the key would be
inserted into the list: the index of
the first element greater than the
key, or list.size(), if all elements
in the list are less than the
specified key. Note that this
guarantees that the return value will
be >= 0 if and only if the key is
found.
I will let you figure out how you can use the return value of Collections.binarySearch to get the answer you need.
Binary search works, but if in fact you have a sorted set of values, then instead of a List, a SortedSet (or even better a NavigableSet), is the most natural data structure of choice.
Here's an example usage:
NavigableSet<Integer> nums = new TreeSet<Integer>(
Arrays.asList(9,1,5,7,3)
);
System.out.println(nums); // "[1, 3, 5, 7, 9]"
System.out.println(nums.first()); // "1"
System.out.println(nums.last()); // "9"
System.out.println(nums.higher(3)); // "5"
System.out.println(nums.lower(8)); // "7"
System.out.println(nums.subSet(2,8)); // "[3, 5, 7]"
System.out.println(nums.subSet(1, true, 5, true)); // "[1, 3, 5]"
There's also NavigableMap counterpart that can be even more useful in some scenarios.