The functional way to do "max" (with recursion / without mutable vars) - java

Finding a max in an unsorted array with imperative code is quite straight forward
e.g. in Java (I'm sure it can be written better, only used for illustration purposes)
public class Main {
public static void main(String[] args) {
int[] array = {1,3,5,4,2};
int max = findMax(array);
System.out.println(max);
}
public static int findMax(int[] array){
int max = Integer.MIN_VALUE; //or array[0], but it requires a null check and I want to keep it simple :)
for (int i = 0, size = array.length; i < size ; i++) {
int current = array[i];
if(current > max) max = current;
}
return max;
}
}
What is the functional way of doing it? e.g.
without mutable variables (e.g. make max be a val in Scala / final in Java)
without looping (e.g. use recursion, tail preferred)
In Scala's sources I saw it was done using recudeLeft, which seems quite clever
def max[B >: A](implicit cmp: Ordering[B]): A = {
if (isEmpty)
throw new UnsupportedOperationException("empty.max")
reduceLeft((x, y) => if (cmp.gteq(x, y)) x else y)
}
But let's say I don't have (for some reason) reduce / reduceLeft available / implemented (And I don't want / can't implement it for some reason, i.e. I'm working with plain Java)
What is the "idiomatic" functional way to do a max without relying on other functional methods (e.g. how would I implement it in bare bones Java for example, but with the functional paradigm in mind)
Answers can be with any language (Java / Scala preferred though)

This is a tail call recursion implementation with accumulator for the max value.
public class Main {
public static void main(String[] args) {
System.out.println(max(new int[]{6, 3, 9, 4}));
}
public static int max(int[] ints) {
return max(ints, Integer.MIN_VALUE);
}
public static int max(int[] ints, int max) {
if (ints.length == 0) {
return max;
} else {
return max(Arrays.copyOfRange(ints, 1, ints.length), ints[0] > max ? ints[0] : max);
}
}
}

You can do it with a plain recursion but maba's tail recursion version should have a better performance.
import java.util.Arrays;
public class TestMax {
public static int findMax(int[] array) {
if(array.length == 1)
return array[0];
int[] newArray = Arrays.copyOfRange(array, 1, array.length);
if(array[0] > findMax(newArray))
return array[0];
else
return findMax(newArray);
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = {1,3,5,4,2, 9};
int max = findMax(array);
System.out.println(max);
}
}

Based on maba's excellent answer here is the Scala version if anyone was interested
def max(list: List[Int]) = {
maxAcc(list, Int.MinValue)
}
def maxAcc(list: List[Int], curMax:Int):Int = {
list match {
case Nil => curMax
case head :: tail => maxAcc(tail, if (head > curMax ) head else curMax )
}
}
Edit: thanks to maba's comment on #tailrec - here is the modified version
def max(list: List[Int]) = {
#tailrec def maxAcc(list: List[Int], curMax: Int): Int = {
list match {
case Nil => curMax
case head :: tail => maxAcc(tail, if (head > curMax) head else curMax)
}
}
maxAcc(list, Int.MinValue)
}

Related

Keep multiplying found values in an array error with recursion

I struggle with this coding "challenge".
I need to look for the original value in nums. If its there, multiply by two
and redo the whole thing.
Return the value if there is no more same value.
It works on a lot of test cases but I get a weird error with this set while debugging.
After I iterate the array and was ready to return the right value, instead of returning the 16, it calls the findFinalValue again and iterates itself from 16 down again to 4.
public class Main {
public static void main(String[] args) {
Solution s = new Solution();
int[] nums = {8,19,4,2,15,3};
System.out.println(s.findFinalValue(nums, 2));
}
}
class Solution {
public int findFinalValue(int[] nums, int original) {
for(int n: nums){
if(n == original){
original*=2;
findFinalValue(nums, original);
}
}
return original;
}
}
It is not iterating from 16 to 4, it is how recursion works. You need to pass the result back or store it in a global variable. Once the dead-end is achieved in recursion it backtracks and comes back to its original state.
Solution
class Solution {
public int findFinalValue(int[] nums, int original) {
int isPresent = false;
for(int n: nums){
if(n == original){
isPresent = true;
break;
}
}
if(isPresent) {
original = findFinalValue(nums, original*2);
}
return original;
}
}
Frankly speaking, you can optimize it by sorting the array at first and then using binary search for finding elements, in addition, the array passed in the next state can be reduced till the index has read. Because original has become twice
I wouldn't use recursion, but since I think you're asking about a recursive solution, I would do it like this:
public int findFinalValue(int[] nums, int original) {
return IntStream.of(nums).anyMatch(n -> n == original)
? findFinalValue(nums, 2 * original)
: original;
}
Guessing that your problem is that your have not implemented recursion properly:
class Solution {
public int findFinalValue(int[] nums, int original) {
int found = original;
for(int n: nums){
if(n == original){
found = findFinalValue(nums, found * 2);
}
}
return found;
}
}

.contains() method not working -- finding an int in array Java

I have been looking for hours, all over the internet and SO, but cannot find anything that I understand! ( Very new at Java )
Upon compiling, it cannot find symbol of the contain method.
Here is the code:
public class LotteryTicket {
private String nameOfBuyer;
private int[] numberList;
private boolean search(int val) {
if (val >= 1 && val <= 50) {
if (numberList.contains(val)) {
return true;
} else {
return false;
}
}
}
I am very new at learning, and I do not know why this is happening.
int[] is a primitive array and does not have a method .contains(). If you used List<Integer> instead, that would give you a .contains() method to call.
Also, your search method must return a value even when val < 1 or val > 50.
If you need numberList to be an int[], you could try this:
private boolean search(int val) {
if (numberList != null && val >= 1 && val <= 50) {
for(int number : numberList) {
if (number == val) {
return true;
}
}
}
return false;
}
Or, you could do this:
private boolean search(int val) {
if (numberList != null && val >= 1 && val <= 50) {
return Arrays.asList(numberList).contains(val);
}
return false;
}
The List interface defines the method contains. Think of an interface as a contract that classes can "sign" (in Java this is done with the keyword implements) which says that the class must have certain things in its implementation. A very common implementation of the List interface is ArrayList, but Lists do not work very well with the primitive int type, so what you want to do is make an ArrayList of Integers.
The simplest way to make an ArrayList of Integers is to make an array of Integers first (I know, Java has a lot of weird steps required to get things working).
In addition, you want to make sure that boolean methods always return a boolean value or you will get a compiler error.
Here's a working example:
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
public class LotteryTicket {
private String nameOfBuyer;
private List<Integer> numberList;
private boolean search(int val) {
return (val >= 1 && val <=50) && numberList.contains(val);
}
public static void main(String[] args) {
LotteryTicket lt = new LotteryTicket();
Integer[] numberList = new Integer[] {2, 3, 4, 5, 42, 6};
lt.numberList = new ArrayList<Integer>(Arrays.asList(numberList));
System.out.println(lt.search(42)); // prints "true\n"
System.out.println(lt.search(25)); // prints "false\n"
}
}

Is it possible to reasonably emulate yield-syntax, perhaps with help of Java 8?

I was experimenting with this question today, from Euler Problems:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
I thought about it and it can of course be done with for-loops, however I want to use Java 8 as it opens up new options.
However first of all, I do not know how to generate an IntStream that produces such elements, so I still ended up using normal for-loops:
public class Problem4 extends Problem<Integer> {
private final int digitsCount;
private int min;
private int max;
public Problem4(final int digitsCount) {
this.digitsCount = digitsCount;
}
#Override
public void run() {
List<Integer> list = new ArrayList<>();
min = (int)Math.pow(10, digitsCount - 1);
max = min * 10;
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
int sum = i * j;
if (isPalindrome(sum)) {
list.add(sum);
}
}
}
result = list.stream().mapToInt(i -> i).max().getAsInt();
}
private boolean isPalindrome(final int number) {
String numberString = String.valueOf(number);
String reversed = new StringBuilder(numberString).reverse().toString();
return (numberString.equals(reversed));
}
#Override
public String getName() {
return "Problem 4";
}
}
As you can see I might be a bit lazy, bit really the IntStream::max is a very nice method and I think it is better to use that, as to write it yourself.
Here comes the issue though, I need to have a list now to be able to obtain the maximum in this manner, which means I need to store data, where I really should not do so.
So, the question now, would it be possible to implement this in Java 8?
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
yield i * j;
}
}
And then out of that method create an PrimitiveIterator.OfInt (unboxes version of Iterator<Integer>, or create an IntStream directly?
Then getting the answer with streamFromYield.filter(this::isPalindrome).max().getAsInt() would be really easy to implement.
Lastly, I know this question has been asked before, however the last time is already quite a bit ago and now Java 8 is going to happen very soon, where they have added as big concept Stream<T> and the new language construct, called lambdas.
So making such code may be very different now than when people were making it for Java 6 or 7.
Well, I think we've gotten carried away using the Streams API from the "outside," using flatMap, optimizing the palindrome-finding algorithm, etc. See answers from Boris the Spider and assylias. However, we've sidestepped the original question of how to write a generator function using something like Python's yield statement. (I think the OP's nested-for example with yield was using Python.)
One of the problems with using flatMap is that parallel splitting can only occur on the outermost stream. The inner streams (returned from flatMap) are processed sequentially. We could try to make the inner streams also parallel, but they'd possibly compete with the outer ones. I suppose nested splitting could work, but I'm not too confident.
One approach is to use the Stream.generate or (like assylias' answer) the Stream.iterate functions. These create infinite streams, though, so an external limit must be supplied to terminate the stream.
It would be nice if we could create a finite but "flattened" stream so that the entire stream of values is subject to splitting. Unfortunately creating a stream is not nearly as convenient as Python's generator functions. It can be done without too much trouble, though. Here's an example that uses the StreamSupport and AbstractSpliterator classes:
class Generator extends Spliterators.AbstractIntSpliterator {
final int min;
final int max;
int i;
int j;
public Generator(int min, int max) {
super((max - min) * (max - min), 0);
this.min = min;
this.max = max;
i = min;
j = min;
}
public boolean tryAdvance(IntConsumer ic) {
if (i == max) {
return false;
}
ic.accept(i * j);
j++;
if (j == max) {
i++;
j = min;
}
return true;
}
}
public static void main(String[] args) {
Generator gen = new Generator(100, 1000);
System.out.println(
StreamSupport.intStream(gen, false)
.filter(i -> isPalindrome(i))
.max()
.getAsInt());
}
Instead of having the iteration variables be on the stack (as in the nested-for with yield approach) we have to make them fields of an object and have the tryAdvance increment them until the iteration is complete. Now, this is the simplest form of a spliterator and it doesn't necessarily parallelize well. With additional work one could implement the trySplit method to do better splitting, which in turn would enable better parallelism.
The forEachRemaining method could be overridden, and it would look almost like the nested-for-loop-with-yield example, calling the IntConsumer instead of yield. Unfortunately tryAdvance is abstract and therefore must be implemented, so it's still necessary to have the iteration variables be fields of an object.
How about looking at it from another direction:
You want a Stream of [100,1000), and for each element of that Stream you want another Stream of that element multiplied by each of [100, 1000). This is what flatMap is for:
public static void main(final String[] args) throws Exception {
OptionalInt max = IntStream.range(100, 1000).
flatMap((i) -> IntStream.range(i, 1000).map((j) -> i * j)).
unordered().
parallel().
filter((i) -> {
String forward = Integer.toString(i);
String backward = new StringBuilder(forward).reverse().toString();
return forward.equals(backward);
}).
max();
System.out.println(max);
}
Not sure if getting a String and then the reverse is the most efficient way to detect palindromes, off the top of my head this would seem to be faster:
final String asString = Integer.toString(i);
for (int j = 0, k = asString.length() - 1; j < k; j++, k--) {
if (asString.charAt(j) != asString.charAt(k)) {
return false;
}
}
return true;
It gives the same answer but I haven't put it under an rigorous testing... Seems to be about 100ms faster on my machine.
Also not sure this problem is big enough for unordered().parallel() - removing that gives a little boost to speed too.
Was just trying to demonstrate the capabilities of the Stream API.
EDIT
As #Stuart points out in the comments, as multiplication is commutative, we only need to IntStream.range(i, 1000) in the sub-stream. This is because once we check a x b we don't need to check b x a. I have updated the answer.
There always have been ways to emulate that overrated yield feature, even without Java 8. Basically it is about storing the state of an execution, i.e. the stack frame(s), which can be done by a thread. A very simple implementation could look like this:
import java.util.Iterator;
import java.util.NoSuchElementException;
public abstract class Yield<E> implements Iterable<E> {
protected interface Flow<T> { void yield(T item); }
private final class State implements Runnable, Iterator<E>, Flow<E> {
private E nextValue;
private boolean finished, value;
public synchronized boolean hasNext() {
while(!(value|finished)) try { wait(); } catch(InterruptedException ex){}
return value;
}
public synchronized E next() {
while(!(value|finished)) try { wait(); } catch(InterruptedException ex){}
if(!value) throw new NoSuchElementException();
final E next = nextValue;
value=false;
notify();
return next;
}
public void remove() { throw new UnsupportedOperationException(); }
public void run() {
try { produce(this); }
finally {
synchronized(this) {
finished=true;
notify();
}
}
}
public synchronized void yield(E next) {
while(value) try { wait(); } catch(InterruptedException ex){}
nextValue=next;
value=true;
notify();
}
}
protected abstract void produce(Flow<E> f);
public Iterator<E> iterator() {
final State state = new State();
new Thread(state).start();
return state;
}
}
Once you have such a helper class, the use case will look straight-forward:
// implement a logic the yield-style
Iterable<Integer> y=new Yield<Integer>() {
protected void produce(Flow<Integer> f) {
for (int i = min; i < max; i++) {
for (int j = min; j < max; j++) {
f.yield(i * j);
}
}
}
};
// use the Iterable, e.g. in a for-each loop
int maxPalindrome=0;
for(int i:y) if(isPalindrome(i) && i>maxPalindrome) maxPalindrome=i;
System.out.println(maxPalindrome);
The previous code didn’t use any Java 8 features. But it will allow using them without the need for any change:
// the Java 8 way
StreamSupport.stream(y.spliterator(), false).filter(i->isPalindrome(i))
.max(Integer::compare).ifPresent(System.out::println);
Note that the Yield support class above is not the most efficient implementation and it doesn’t handle the case if an iteration is not completed but the Iterator abandoned. But it shows that such a logic is indeed possible to implement in Java (while the other answers convincingly show that such a yield logic is not necessary to solve such a problem).
I'll give it a go. Version with a loop then with a stream. Although I start from the other end so it's easier because I can limit(1).
public class Problem0004 {
public static void main(String[] args) {
int maxNumber = 999 * 999;
//with a loop
for (int i = maxNumber; i > 0; i--) {
if (isPalindrome(i) && has3DigitsFactors(i)) {
System.out.println(i);
break;
}
}
//with a stream
IntStream.iterate(maxNumber, i -> i - 1)
.parallel()
.filter(i -> isPalindrome(i) && has3DigitsFactors(i))
.limit(1)
.forEach(System.out::println);
}
private static boolean isPalindrome(int n) {
StringBuilder numbers = new StringBuilder(String.valueOf(n));
return numbers.toString().equals(numbers.reverse().toString());
}
private static boolean has3DigitsFactors(int n) {
for (int i = 999; i > 0; i--) {
if (n % i == 0 && n / i < 1000) {
return true;
}
}
return false;
}
}

Basic recursive method - factorial

I am practicing recursion and I can't see why this method does not seem to work.
Any ideas?
public void fact()
{
fact(5);
}
public int fact(int n)
{
if(n == 1){
return 1;
}
return n * (fact(n-1));
}
}
Thanks
Your code seems to work but you are not doing anything with the returned value, put method call fact or fact(5) inside of a System.out.println and see what you get.
The recursion part is fine; you're just not using its return value, which gets discarded. Here's a complete Java application of your factorial code, slightly jazzed-up for educational purposes:
public class Factorial {
public static String fact(int n) {
if(n == 1){
return "1";
}
return n + " * " + (fact(n-1)); // what happens if you switch the order?
}
public static void main(String[] args) {
System.out.println(fact(5));
// prints "5 * 4 * 3 * 2 * 1"
}
}
A simplified version of your code:
public int fact(int n)
{
if(n == 1){
return 1;
}
return n * (fact(n-1));
}
could be just:
public int fact(int n)
{
return n == 1 ? 1 : n * fact(n - 1);
}
but your code is not wrong, this is just another style (if you are not used to ternary operator keep the way it is). I prefer use the ternary operator in these cases (observe that the code is side effect free).
Works fine. You're not assigning it to anything. Here's a test that'll prove it works.
#Test
public void testYourFactorialMethod() {
assertEquals(120, fact(5));
}
public class Recursive {
public static void main(String[] argss) {
System.out.print(fac(3));
}
public static int fac(int n) {
int value = 0;
if (n == 0) {
value = 1;
} else {
value = n * fac(n - 1);
}
return value;
}
}
// out put 6
Try something like this:
(Or maybe try this directly)
public class factorial {
private static int factorial( int n ){
if (n > 1) {
return n * (factorial(n-1));
} else {
return 1;
}
}
public static void main(String[] args) {
System.out.println(factorial(100));
}
}
static int factorial(int x) {
int result;
if (x == 1) {
return 1;
}
// Call the same method with argument x-1
result = factorial(x – 1) * x;
return result;
}
For complete example check this
http://answersz.com/factorial-program-in-java-using-recursion/
It is totaly wrong to write Fibonacci with recursive methods!!
It is an old famous example for how a good/bad Algorythm affect any project
if you write Fibonatcci recursive, for calculating 120 you need 36 year toget the result!!!!!!
public static int Fibonacci(int x)
{ // bad fibonacci recursive code
if (x <= 1)
return 1;
return Fibonacci(x - 1) + Fibonacci(x - 2);
}
in dot net 4.0 there is a new type name BigInteger and you can use it to make a better function
using System;
using System.Collections.Generic;
using System.Numerics; //needs a ref. to this assembly
namespace Fibonaci
{
public class CFibonacci
{
public static int Fibonacci(int x)
{
if (x <= 1)
return 1;
return Fibonacci(x - 1) + Fibonacci(x - 2);
}
public static IEnumerable<BigInteger> BigFib(Int64 toNumber)
{
BigInteger previous = 0;
BigInteger current = 1;
for (Int64 y = 1; y <= toNumber; y++)
{
var auxiliar = current;
current += previous;
previous = auxiliar;
yield return current;
}
}
}
}
and you can use it like
using System;
using System.Linq;
namespace Fibonaci
{
class Program
{
static void Main()
{
foreach (var i in CFibonacci.BigFib(10))
{
Console.WriteLine("{0}", i);
}
var num = 12000;
var fib = CFibonacci.BigFib(num).Last();
Console.WriteLine("fib({0})={1}", num, fib);
Console.WriteLine("Press a key...");
Console.ReadKey();
}
}
}
and in this case you can calculate 12000 less than a second. so
Using Recursive methos is not always a good idea
Above code imported from Vahid Nasiri blog whiche wrote in Persian

Picking a random element from a set

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;
}

Categories