public class MyArrayList<T> implements MyList<T>{
int num; //number of things in the list
T[] vals; //to store the contents
#SuppressWarnings("unchecked")
public MyArrayList() {
num = 0;
vals = (T[]) new Object[3];
}
public T getUnique(){
T distinct = null;
int count = 0;
for (int i=0; i<vals.length; i++){
distinct = vals[i];
for (int j = 0; j<vals.length; j++){
if (vals[j] == vals[i]){
count++;
}
if (count == 1){
return distinct;
}
}
}
if (distinct == null){
throw new IllegalArgumentException();
}
return distinct;
}
I am trying to work on a get Unique Method. A method getUnique that takes no arguments and returns the first value in the list that appears only once. (For example, calling the method on the list [1,2,3,1,2,4] would return 3 since 1 and
2 both appear more than once.) If the list is empty or all its values appear more than once, the method throws a NoSuchElementException
I have added some FIXME's to your code:
public T getUnique(){
T distinct = null;
int count = 0; // FIXME: move this initialization inside the i loop
for (int i=0; i<vals.length; i++){
distinct = vals[i];
for (int j = 0; j<vals.length; j++){
if (vals[j] == vals[i]){ // FIXME: use .equals() not ==
count++;
}
if (count == 1){ // FIXME: move this check outside the j loop
return distinct;
}
}
}
if (distinct == null){ //FIXME: no check needed, just throw it
throw new IllegalArgumentException();
}
return distinct; //FIXME: no valid return can reach this point
}
Patrick Parker's advice will fix your code, but I wanted to provide a cleaner and faster solution to the problem of finding a unique element in a list. This algorithm runs in time O(n) instead of O(n^2).
public static <T> Optional<T> getUnique(List<T> ls) {
// Create a map whose keys are elements of the list and whose values are
// lists of their occurences. E.g. [1,2,3,1,2,4] becomes {1->[1, 1],
// 2->[2, 2], 3->[3], 4->[4]}. Then elements.get(x).size() tells us how
// many times x occured in ls.
Map<T, List<T>> elements = ls.stream()
.collect(Collectors.groupingBy(x -> x));
// Find the first element that occurs exactly one time in ls.
return ls.stream().filter(x -> elements.get(x).size() == 1)
.findFirst();
}
You might call it like this:
Integer[] vals = {1,2,3,1,2,4};
System.out.println(getUnique(Arrays.asList(vals))
.orElseThrow(NoSuchElementException::new));
This code uses Java 8 streams and Optional. Below is another implementation of the same algorithm that doesn't use Java 8 language features; if you've never encountered streams, you may find it more understandable.
private static <T> T getUnique(List<T> arr) {
Map<T, Integer> numOccurrences = new HashMap<>();
for (T item : arr) {
numOccurrences.put(item, 1 + numOccurrences.getOrDefault(item, 0));
}
for (T item : arr) {
if (numOccurrences.get(item) == 1) {
return item;
}
}
throw new NoSuchElementException();
}
How do I pick a random element from a set?
I'm particularly interested in picking a random element from a
HashSet or a LinkedHashSet, in Java.
Solutions for other languages are also welcome.
int size = myHashSet.size();
int item = new Random().nextInt(size); // In real life, the Random object should be rather more shared than this
int i = 0;
for(Object obj : myhashSet)
{
if (i == item)
return obj;
i++;
}
A somewhat related Did You Know:
There are useful methods in java.util.Collections for shuffling whole collections: Collections.shuffle(List<?>) and Collections.shuffle(List<?> list, Random rnd).
In Java 8:
static <E> E getRandomSetElement(Set<E> set) {
return set.stream().skip(new Random().nextInt(set.size())).findFirst().orElse(null);
}
Fast solution for Java using an ArrayList and a HashMap: [element -> index].
Motivation: I needed a set of items with RandomAccess properties, especially to pick a random item from the set (see pollRandom method). Random navigation in a binary tree is not accurate: trees are not perfectly balanced, which would not lead to a uniform distribution.
public class RandomSet<E> extends AbstractSet<E> {
List<E> dta = new ArrayList<E>();
Map<E, Integer> idx = new HashMap<E, Integer>();
public RandomSet() {
}
public RandomSet(Collection<E> items) {
for (E item : items) {
idx.put(item, dta.size());
dta.add(item);
}
}
#Override
public boolean add(E item) {
if (idx.containsKey(item)) {
return false;
}
idx.put(item, dta.size());
dta.add(item);
return true;
}
/**
* Override element at position <code>id</code> with last element.
* #param id
*/
public E removeAt(int id) {
if (id >= dta.size()) {
return null;
}
E res = dta.get(id);
idx.remove(res);
E last = dta.remove(dta.size() - 1);
// skip filling the hole if last is removed
if (id < dta.size()) {
idx.put(last, id);
dta.set(id, last);
}
return res;
}
#Override
public boolean remove(Object item) {
#SuppressWarnings(value = "element-type-mismatch")
Integer id = idx.get(item);
if (id == null) {
return false;
}
removeAt(id);
return true;
}
public E get(int i) {
return dta.get(i);
}
public E pollRandom(Random rnd) {
if (dta.isEmpty()) {
return null;
}
int id = rnd.nextInt(dta.size());
return removeAt(id);
}
#Override
public int size() {
return dta.size();
}
#Override
public Iterator<E> iterator() {
return dta.iterator();
}
}
This is faster than the for-each loop in the accepted answer:
int index = rand.nextInt(set.size());
Iterator<Object> iter = set.iterator();
for (int i = 0; i < index; i++) {
iter.next();
}
return iter.next();
The for-each construct calls Iterator.hasNext() on every loop, but since index < set.size(), that check is unnecessary overhead. I saw a 10-20% boost in speed, but YMMV. (Also, this compiles without having to add an extra return statement.)
Note that this code (and most other answers) can be applied to any Collection, not just Set. In generic method form:
public static <E> E choice(Collection<? extends E> coll, Random rand) {
if (coll.size() == 0) {
return null; // or throw IAE, if you prefer
}
int index = rand.nextInt(coll.size());
if (coll instanceof List) { // optimization
return ((List<? extends E>) coll).get(index);
} else {
Iterator<? extends E> iter = coll.iterator();
for (int i = 0; i < index; i++) {
iter.next();
}
return iter.next();
}
}
If you want to do it in Java, you should consider copying the elements into some kind of random-access collection (such as an ArrayList). Because, unless your set is small, accessing the selected element will be expensive (O(n) instead of O(1)). [ed: list copy is also O(n)]
Alternatively, you could look for another Set implementation that more closely matches your requirements. The ListOrderedSet from Commons Collections looks promising.
In Java:
Set<Integer> set = new LinkedHashSet<Integer>(3);
set.add(1);
set.add(2);
set.add(3);
Random rand = new Random(System.currentTimeMillis());
int[] setArray = (int[]) set.toArray();
for (int i = 0; i < 10; ++i) {
System.out.println(setArray[rand.nextInt(set.size())]);
}
List asList = new ArrayList(mySet);
Collections.shuffle(asList);
return asList.get(0);
This is identical to accepted answer (Khoth), but with the unnecessary size and i variables removed.
int random = new Random().nextInt(myhashSet.size());
for(Object obj : myhashSet) {
if (random-- == 0) {
return obj;
}
}
Though doing away with the two aforementioned variables, the above solution still remains random because we are relying upon random (starting at a randomly selected index) to decrement itself toward 0 over each iteration.
Clojure solution:
(defn pick-random [set] (let [sq (seq set)] (nth sq (rand-int (count sq)))))
Java 8+ Stream:
static <E> Optional<E> getRandomElement(Collection<E> collection) {
return collection
.stream()
.skip(ThreadLocalRandom.current()
.nextInt(collection.size()))
.findAny();
}
Based on the answer of Joshua Bone but with slight changes:
Ignores the Streams element order for a slight performance increase in parallel operations
Uses the current thread's ThreadLocalRandom
Accepts any Collection type as input
Returns the provided Optional instead of null
Perl 5
#hash_keys = (keys %hash);
$rand = int(rand(#hash_keys));
print $hash{$hash_keys[$rand]};
Here is one way to do it.
C++. This should be reasonably quick, as it doesn't require iterating over the whole set, or sorting it. This should work out of the box with most modern compilers, assuming they support tr1. If not, you may need to use Boost.
The Boost docs are helpful here to explain this, even if you don't use Boost.
The trick is to make use of the fact that the data has been divided into buckets, and to quickly identify a randomly chosen bucket (with the appropriate probability).
//#include <boost/unordered_set.hpp>
//using namespace boost;
#include <tr1/unordered_set>
using namespace std::tr1;
#include <iostream>
#include <stdlib.h>
#include <assert.h>
using namespace std;
int main() {
unordered_set<int> u;
u.max_load_factor(40);
for (int i=0; i<40; i++) {
u.insert(i);
cout << ' ' << i;
}
cout << endl;
cout << "Number of buckets: " << u.bucket_count() << endl;
for(size_t b=0; b<u.bucket_count(); b++)
cout << "Bucket " << b << " has " << u.bucket_size(b) << " elements. " << endl;
for(size_t i=0; i<20; i++) {
size_t x = rand() % u.size();
cout << "we'll quickly get the " << x << "th item in the unordered set. ";
size_t b;
for(b=0; b<u.bucket_count(); b++) {
if(x < u.bucket_size(b)) {
break;
} else
x -= u.bucket_size(b);
}
cout << "it'll be in the " << b << "th bucket at offset " << x << ". ";
unordered_set<int>::const_local_iterator l = u.begin(b);
while(x>0) {
l++;
assert(l!=u.end(b));
x--;
}
cout << "random item is " << *l << ". ";
cout << endl;
}
}
Solution above speak in terms of latency but doesn't guarantee equal probability of each index being selected.
If that needs to be considered, try reservoir sampling. http://en.wikipedia.org/wiki/Reservoir_sampling. Collections.shuffle() (as suggested by few) uses one such algorithm.
Since you said "Solutions for other languages are also welcome", here's the version for Python:
>>> import random
>>> random.choice([1,2,3,4,5,6])
3
>>> random.choice([1,2,3,4,5,6])
4
Can't you just get the size/length of the set/array, generate a random number between 0 and the size/length, then call the element whose index matches that number? HashSet has a .size() method, I'm pretty sure.
In psuedocode -
function randFromSet(target){
var targetLength:uint = target.length()
var randomIndex:uint = random(0,targetLength);
return target[randomIndex];
}
PHP, assuming "set" is an array:
$foo = array("alpha", "bravo", "charlie");
$index = array_rand($foo);
$val = $foo[$index];
The Mersenne Twister functions are better but there's no MT equivalent of array_rand in PHP.
Icon has a set type and a random-element operator, unary "?", so the expression
? set( [1, 2, 3, 4, 5] )
will produce a random number between 1 and 5.
The random seed is initialized to 0 when a program is run, so to produce different results on each run use randomize()
In C#
Random random = new Random((int)DateTime.Now.Ticks);
OrderedDictionary od = new OrderedDictionary();
od.Add("abc", 1);
od.Add("def", 2);
od.Add("ghi", 3);
od.Add("jkl", 4);
int randomIndex = random.Next(od.Count);
Console.WriteLine(od[randomIndex]);
// Can access via index or key value:
Console.WriteLine(od[1]);
Console.WriteLine(od["def"]);
Javascript solution ;)
function choose (set) {
return set[Math.floor(Math.random() * set.length)];
}
var set = [1, 2, 3, 4], rand = choose (set);
Or alternatively:
Array.prototype.choose = function () {
return this[Math.floor(Math.random() * this.length)];
};
[1, 2, 3, 4].choose();
In lisp
(defun pick-random (set)
(nth (random (length set)) set))
How about just
public static <A> A getRandomElement(Collection<A> c, Random r) {
return new ArrayList<A>(c).get(r.nextInt(c.size()));
}
For fun I wrote a RandomHashSet based on rejection sampling. It's a bit hacky, since HashMap doesn't let us access it's table directly, but it should work just fine.
It doesn't use any extra memory, and lookup time is O(1) amortized. (Because java HashTable is dense).
class RandomHashSet<V> extends AbstractSet<V> {
private Map<Object,V> map = new HashMap<>();
public boolean add(V v) {
return map.put(new WrapKey<V>(v),v) == null;
}
#Override
public Iterator<V> iterator() {
return new Iterator<V>() {
RandKey key = new RandKey();
#Override public boolean hasNext() {
return true;
}
#Override public V next() {
while (true) {
key.next();
V v = map.get(key);
if (v != null)
return v;
}
}
#Override public void remove() {
throw new NotImplementedException();
}
};
}
#Override
public int size() {
return map.size();
}
static class WrapKey<V> {
private V v;
WrapKey(V v) {
this.v = v;
}
#Override public int hashCode() {
return v.hashCode();
}
#Override public boolean equals(Object o) {
if (o instanceof RandKey)
return true;
return v.equals(o);
}
}
static class RandKey {
private Random rand = new Random();
int key = rand.nextInt();
public void next() {
key = rand.nextInt();
}
#Override public int hashCode() {
return key;
}
#Override public boolean equals(Object o) {
return true;
}
}
}
The easiest with Java 8 is:
outbound.stream().skip(n % outbound.size()).findFirst().get()
where n is a random integer. Of course it is of less performance than that with the for(elem: Col)
With Guava we can do a little better than Khoth's answer:
public static E random(Set<E> set) {
int index = random.nextInt(set.size();
if (set instanceof ImmutableSet) {
// ImmutableSet.asList() is O(1), as is .get() on the returned list
return set.asList().get(index);
}
return Iterables.get(set, index);
}
In Mathematica:
a = {1, 2, 3, 4, 5}
a[[ ⌈ Length[a] Random[] ⌉ ]]
Or, in recent versions, simply:
RandomChoice[a]
Random[] generates a pseudorandom float between 0 and 1. This is multiplied by the length of the list and then the ceiling function is used to round up to the next integer. This index is then extracted from a.
Since hash table functionality is frequently done with rules in Mathematica, and rules are stored in lists, one might use:
a = {"Badger" -> 5, "Bird" -> 1, "Fox" -> 3, "Frog" -> 2, "Wolf" -> 4};
PHP, using MT:
$items_array = array("alpha", "bravo", "charlie");
$last_pos = count($items_array) - 1;
$random_pos = mt_rand(0, $last_pos);
$random_item = $items_array[$random_pos];
you can also transfer the set to array use array
it will probably work on small scale i see the for loop in the most voted answer is O(n) anyway
Object[] arr = set.toArray();
int v = (int) arr[rnd.nextInt(arr.length)];
If you really just want to pick "any" object from the Set, without any guarantees on the randomness, the easiest is taking the first returned by the iterator.
Set<Integer> s = ...
Iterator<Integer> it = s.iterator();
if(it.hasNext()){
Integer i = it.next();
// i is a "random" object from set
}
A generic solution using Khoth's answer as a starting point.
/**
* #param set a Set in which to look for a random element
* #param <T> generic type of the Set elements
* #return a random element in the Set or null if the set is empty
*/
public <T> T randomElement(Set<T> set) {
int size = set.size();
int item = random.nextInt(size);
int i = 0;
for (T obj : set) {
if (i == item) {
return obj;
}
i++;
}
return null;
}
So I have this code:
public class SortedIntList extends IntList
{
private int[] newlist;
public SortedIntList(int size)
{
super(size);
newlist = new int[size];
}
public void add(int value)
{
for(int i = 0; i < list.length; i++)
{
int count = 0,
current = list[i];
if(current < value)
{
newlist[count] = current;
count++;
}
else
{
newlist[count] = value;
count++;
}
}
}
}
Yet, when I run the test, nothing prints out. I have the system.out.print in another class in the same source.
Where am I going wrong?
EDIT: Print code from comment:
public class ListTest
{
public static void main(String[] args)
{
SortedIntList myList = new SortedIntList(10);
myList.add(100);
myList.add(50);
myList.add(200);
myList.add(25);
System.out.println(myList);
}
}
EDIT2: Superclass from comment below
public class IntList
{
protected int[] list;
protected int numElements = 0;
public IntList(int size)
{
list = new int[size];
}
public void add(int value)
{
if (numElements == list.length)
System.out.println("Can't add, list is full");
else {
list[numElements] = value; numElements++;
}
}
public String toString()
{
String returnString = "";
for (int i=0; i<numElements; i++)
returnString += i + ": " + list[i] + "\n";
return returnString;
}
}
Let's walk through the logic of how you want it to work here:
first you make a new sorted list passing 10 to the constructor, which make an integer array of size 10.
now you call your add method passing 100 into it. the method sets position 0 to 100
now you add 50, the method sets 50 in position 0 and 100 in position 1
now you add 200, which gets placed at position 2
and you add 25. which gets set to position 0, and everything else gets shuffled on down
then your method will print out everything in this list.
So here are your problems:
For the first add, you compare current, which is initialized at 0, to 50. 0 will always be less than 50, so 50 never gets set into the array. This is true for all elements.
EDIT: Seeing the super class this is how you should look to fix your code:
public class SortedIntList extends IntList
{
private int[] newlist;
private int listSize;
public SortedIntList(int size)
{
super(size);
// I removed the newList bit becuase the superclass has a list we are using
listSize = 0; // this keeps track of the number of elements in the list
}
public void add(int value)
{
int placeholder;
if (listSize == 0)
{
list[0] = value; // sets first element eqal to the value
listSize++; // incriments the size, since we added a value
return; // breaks out of the method
}
for(int i = 0; i < listSize; i++)
{
if (list[i] > value) // checks if the current place is greater than value
{
placeholder = list[i]; // these three lines swap the value with the value in the array, and then sets up a comparison to continue
list[i] = value;
value = placeholder;
}
}
list[i] = value; // we are done checking the existing array, so the remaining value gets added to the end
listSize++; // we added an element so this needs to increase;
}
public String toString()
{
String returnString = "";
for (int i=0; i<listSize; i++)
returnString += i + ": " + list[i] + "\n";
return returnString;
}
}
Now that I see the superclass, the reason why it never prints anything is clear. numElements is always zero. You never increment it because you never call the superclass version of the add method.
This means that the loop in the toString method is not iterated at all, and toString always just returns empty string.
Note
This is superseded by my later answer. I have left it here, rather than deleting it, in case the information in it is useful to you.
Two problems.
(1) You define list in the superclass, and presumably that's what you print out; but you add elements to newList, which is a different field.
(2) You only add as many elements to your new list as there are in your old list. So you'll always have one element too few. In particular, when you first try to add an element, your list has zero elements both before and after the add.
You should probably have just a single list, not two of them. Also, you should break that for loop into two separate loops - one loop to add the elements before the value that you're inserting, and a second loop to add the elements after it.
I have to make a custom iterator that iterators through an array endlessly. I have no clue how to do this considering I've never worked with iterators in java before. If anyone could help me out at all and explain to me, I'd appreciate it very much.
public class Numbers{
private int[] array;
public Numbers(int[] array){
this.array = array
}
public static void main(String[] args) {
Numbers n = new Numbers();
Iterator num = n.sequence();
for(int i = 0; i < 10; i++){
if (num.hasNext()){
System.out.print(num.next() + " ");
System.out.println();
}
}
}
}
See below:
public class Numbers implements Iterable<Integer> {
private int[] array;
private int i;
public Numbers(int[] array) {
this.array = array;
i = 0;
}
public Iterator<Integer> iterator() {
return new Iterator<Integer>() {
#Override
public boolean hasNext() { return true; }
#Override
public Integer next() {
int j = i;
i = (i + 1) % array.length;
return array[j];
}
#Override
public void remove() {}
};
}
}
You could then do:
Numbers n = new Numbers(new int[]{1,2,3});
for (int i : n)
System.out.println(i); // or anything else
This would result in the infinite loop:
1
2
3
1
2
3
1
2
...
Relevant javadocs:
- Iterator
- Iterable
Another way to do it is just to have an infinite while-loop as such:
int[] array = new int[]{1, 2, 3};
int i = 0;
while (true) {
System.out.println(array[i]); // or anything else
i = (i + 1) % array.length;
}
This is basically how an iterator works. This example uses a List, but you can use an iterator against any collection that implements java.lang.Iterable.
List<String> someList; // assume this has been instantiated and has values in it
ListIterator<String> it = someList.listIterator();
while (it.hasNext()) {
String value = it.next();
// do something with value
}
Pretty much, you instantiate the iterator by telling the collection to give you a reference to its iterator. Then you loop by calling hasNext(), which will keep you going until you have no more elements. The call to next() pulls the next item from the iterator and increments its position by one. A call to remove() will remove from the list the last item returned by next() (or previous().)
Note, of course, that I've been using java.util.ListIterator instead of java.util.Iterator because the ListIterator is a special implementation of Iterator optimized for use against lists, like in the example I gave above.
You cannot use an iterator against an array. You'd need to use a vanilla for-loop or convert it into a List or another object that implements Iterable.
To loop through the above list endlessly, your loop would look something like this:
while(it.hasNext()) {
String value = it.next();
// do processing
if (!it.hasNext()) {
it = someList.listIterator(); // reset the iterator
}
}
To loop through the array using a for-loop endlessly:
for (int i = 0; i < myArray.length; i++) {
myArray[i];
// do something
if (i == myArray.length - 1) {
i = 0; // reset the index
}
}
Alteratively you could have your Numbers class implement Iterable directly.
Work with iterators is basically always the same.
First get the iterator from your array:
Iterator iterator = yourArray.iterator();
Second iterate while it has items:
while(iterator.hasNext()) {
Object element = iterator.next();
}
The lists are sorted the way they are supposed to but when I try to merge the two lists together in my makeUnion it prints out the list is empty. can anyone help me and tell my why? in main when I try SortedLinkedList merge = sortedNames1.makeUnion(sortedNames2) I get "Empty list".
public class SortedLinkedList<T extends Comparable<? super T>>
extends LinkedList<T>
{
private LinkedList<T> list; //the sorted list
//the constructor
public SortedLinkedList(LinkedList<T> in)
{
if(in.isEmpty())
{
System.out.println("Empty list");
}
if(in.size() < 2)
{
return;
}
else
{
list = new LinkedList<T>();
for(int i = 1; i < in.size(); i++)
{
T temp = in.get(i);
int j = i;
while(j > 0 && in.get(j - 1).compareTo(temp) > 0)
{
in.set(j, in.get(j-1));
j--;
}
in.set(j, temp);
}
for(T elements : in)
{
list.add(elements);
}
}
}
//return the union of the sorted linked lists this and other
public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
SortedLinkedList<T> first = new SortedLinkedList<T>(other);
SortedLinkedList<T> second = new SortedLinkedList<T>(list);
SortedLinkedList<T> UnionList = null;
int i = 0;
int j = 0;
while(i<first.size() && j<second.size())
{
if(first.get(i).compareTo(second.get(j)) <= 0)
{
UnionList.add(first.get(i));
i++;
}
else
{
UnionList.add(second.get(j));
j++;
}
}
if(i == first.size())
{
for(int k = j; k<second.size(); k++)
{
UnionList.add(second.get(k));
}
}
else if(j == second.size())
{
for(int x = i; x<first.size(); x++)
{
UnionList.add(first.get(x));
}
}
return UnionList;
}
//print the items int list
public void print()
{
ListIterator itr = list.listIterator();
while(itr.hasNext())
{
System.out.println(itr.next());
}
}
}
SortedLinkedList<T> UnionList = null;
You can't call UnionList.add() if UnionList is null. You will need to allocate a new list before you can add things to it.
Actually, I think your original problem might be that SortedLinkedList both extends LinkedList and also contains an instance of a LinkedList. You should choose one or the other, but not both. Your code sometimes accesses one list, and sometimes the other, so one list appears empty because you've added items to the other list.
You don't initialize UnionList before you start using it.
SortedLinkedList<T> UnionList = null;
should read
SortedLinkedList<T> UnionList = new SortedLinkedList<T>();
As a bonus, ListIterator ought to be ListIterator<T> so that the right toString() method is used. As it is, you'll be calling Object.toString().
Because you used inheritance instead of delegation. You inherit LinkedList, and the only thing you do is define a constructor which adds the content of an unsorted list to a new one, in the appropriate order. But you don't override the size method, so this method is inherited from LinkedList, which doesn't care about your internal sorted list and thus always returns 0.
Extending a collection is, most of the time, a bad idea. In this case, it's a particularly bad idea because it's impossible to have a sorted LinkedList that respects the LinkedList API. Suppose your list contains A, B and C, and you call addFirst("Z") on it. Where will you put Z, if at the beginning, your list is not sorted anymore. If at the end, you don't respect the contract of addFirst.
Just use linked lists (instead of extending them), and sort them. You could just do :
LinkedList list = new LinkedList(someUnsortedList);
Collections.sort(list); // now the list is sorted
list.addAll(someOtherList);
Collections.sort(list); // now both lists are merged, and the resulting list is sorted.