Duplicate number check doesn't always work - java

I have a function getNormalList() that must return a list with 3 random integers 0-5, not all the same. It's not working like I want it to work. Sometimes, despite the check, it outputs the same 3 numbers.
public class SpinResultGenerator {
public ArrayList<Integer> getNormalList() {
ArrayList<Integer> integerList = new ArrayList<Integer>();
Random r = new Random();
int Low = 0;
int High = 6;
for (int i = 0; i < 3; i++) {
int number = r.nextInt(High - Low) + Low;
integerList.add(number);
}
if (integerList.get(0) == integerList.get(1) && integerList.get(0) == integerList.get(2)
&& integerList.get(1) == integerList.get(2)) {
integerList.clear();
for (int i = 0; i < 3; i++) {
int number = r.nextInt(High - Low) + Low;
integerList.add(number);
}
}
return integerList;
}
public ArrayList<Integer> getJackpotList() {
ArrayList<Integer> integerList = new ArrayList<Integer>();
integerList.add(5);
integerList.add(5);
integerList.add(5);
return integerList;
}
}
If the result is, for example, [4,4,4], the for loop generates new numbers. Yet it is still able to output 3 of the same integers. Why?

You need a nested loop. Your for loop should repeat until 3 acceptable numbers are found. I used an array to make the code more compact, but the same can be done with ArrayList.
public List<Integer> getNormalList() {
Random r = new Random();
int[] arr = new int[3]; // initialized to 0s by default
int Low = 0;
int High = 6;
while (arr[0] == arr[1] && arr[1] == arr[2]) { // will repeat as long as the 3 number as
// all equal
for (int i = 0; i < arr.length; i++) {
arr[i] = r.nextInt(High - Low) + Low;
}
}
return Arrays.asList(arr);
}

Your current code fails because if it generates a list of duplicates, it just clears it and generates a new list, without checking if the new list contains duplicates. Here's my suggested alternate solution:
do {
List<Integer> result = ThreadLocalRandom.current().ints(0, 6).limit(3).boxed().collect(toList())
} while (result.get(0) == result.get(1) && result.get(0) == result.get(2))
return result;

Related

Generating random numbers array in Java

I'm working on a code that should generate an array with a length of 100 and then separates numbers form the array to:
Numbers that are multiples of 4.
Numbers that are not multiples of 4.
Below is my code, however, I'm getting a weird output (lots of zeros). How can I identify the problem?
public class Assignment8 {
public static void main(String[] args) {
// Defined array to hold the values
int[] randomValueArray = new int[100];
int[] mod4ValueArray = new int[100];
int[] nonMod4ValueArray = new int[100];
// Initiate the randomValue Array
for (int i = 0; i < 100; ++i) {
// Generate a random number from the range 1 to 100
int randomValue = (int) (Math.random() * 100 + 1);
randomValueArray[i] = randomValue;
}
// Pass the array to the class method to separate mod4
// value and non mod4 value from the randomized array
mod4ValueArray = isMod4(randomValueArray);
nonMod4ValueArray = isNonMod4(randomValueArray);
// Print out the two result arrays
System.out.println("Randomly generated numbers that are multiples of four: ");
for (int i = 0; i < mod4ValueArray.length; ++i) {
System.out.println(mod4ValueArray[i]);
}
System.out.println("Randomly generated numbers that are not multiples of four: ");
for (int i = 0; i < nonMod4ValueArray.length; ++i) {
System.out.println(nonMod4ValueArray[i]);
}
}
// Mod4 Checker Method
public static int[] isMod4(int[] array) {
int[] resultArray = new int[array.length];
for (int i = 0; i < array.length; ++i) {
int itemValue = array[i];
if ((array[i] % 4) == 0) {
resultArray[i] = itemValue;
}
}
return resultArray;
}
// Non Mod 4 Checker Method
public static int[] isNonMod4(int[] array) {
int[] resultArray = new int[array.length];
for (int i = 0; i < array.length; ++i) {
int itemValue = array[i];
if ((itemValue % 4) != 0) {
resultArray[i] = itemValue;
}
}
return resultArray;
}
}
Try this.
int[] randomValueArray = new Random().ints(100, 1, 101).toArray();
int[] mod4ValueArray = IntStream.of(randomValueArray).filter(i -> i % 4 == 0).toArray();
int[] nonMod4ValueArray = IntStream.of(randomValueArray).filter(i -> i % 4 != 0).toArray();
try this:
new Random().ints(100, 1, 100).filter(n -> n % 4 == 0).toArray();
new Random().ints(100, 1, 100).filter(n -> n % 4 != 0).toArray();
Java 8 Stream-esque solution:
Map<Boolean, int[]> map = new Random().ints(10, 1, 100)
.mapToObj(i -> i)
.collect(partitioningBy(i -> i % 4 == 0, collectingAndThen(toList(), list -> list.stream()
.mapToInt(i -> i)
.toArray()
)));
This pulls 100 random integers from 1 to 100, then boxes all ints to Integers, then partitions by whether the number is dividable by 4. Then, the resulting List<Integer> is converted to an int[].
However, I think a plain old for loop is better. The only difficulty you have, is that you don't know how large each array will get. So at the end, you'll need to resize the arrays.
int[] fourMods = new int[100];
int[] nonFourMods = new int[100];
int fourModsCardinality = 0;
int nonFourModsCardinality = 0;
Random random = new Random();
for (int i = 0; i < 100; i++) {
int num = random.nextInt(100) + 1;
if (num % 4 == 0) {
fourMods[fourModsCardinality] = num;
fourModsCardinality++;
}
else {
nonFourMods[fourModsCardinality] = num;
nonFourModsCardinality++;
}
}

Want to use an array created in a method, for further use in another method

I have a problem and the title actually sums it up perfectly. So i'll just go ahead and show you the code snippet.
So the methode generate, is generating an array, that is filled with numbers between 1 and 1000, including both. The length of the array is user input.
The next method, isPrime, is gonna conclude if its a prime number, so i can use those numbers with the true condition in another method. The generate method works but in isPrime i always get errors. If u can think of a better way, let me know please.
static int[] generate(int n) {
int[] arr = new int[n+1];
for(int x = 0; x <= n; x ++) {
int number = (int) (Math.random()* 999)+1;
arr[x] = number;
}
return arr;
}
static int isPrime(int p, final int q[]) {
boolean itIs = true;
//final int[] arr;
for(int r = 0; r <= p; r++) { // here it somehow states r is deadCode
for(int j = 2; j < q[r]; j++) {
if(q[r]%j == 0) {
itIs = false;
}
}
return q[r];
}
}
First, create a method to check a value is prime:
public boolean isPrime(int value) {
for (int i = 0; i < value / 2; i++) { // value / 2 is enough, doesn't need to check all values
if (value % i == 0) {
return false;
}
}
return true;
}
Then you check each value of array and put prime value to new array:
public int[] filterArray(int[] array) {
List<Integer> intList = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
if (isPrime(array[i])) {
intList.add(array[i]);
}
}
Integer[] integerArray = intList.toArray(new Integer[intList.size()]);
int[] intArray = ArrayUtils.toPrimitive(integerArray);
return intArray;
}
Then you get the filtered prime array.

Java - Program to find longest increasing sequence of consecutive elements (logical errors)

I am currently creating a program where the user inputs an array of integers. The program has to find the longest increasing sequence of consecutive elements. So if the user enters "3,2,1,2,4,6,7,8,1,2" the program will output "1,2,4,5,6,7,8". However, I keep running into 2 errors.
The first error is that when xs = 1000,97777,487,8274,972837. The program will output "1000,97777" instead of "487,8274,972837". Logically this is wrong since the first output is not the "LONGEST" increasing sequence of consecutive element.
The second error is that when xs = 2,7. It seems to output an empty array instead of "2,7". I'm assuming it's because there aren't enough elements perhaps?
static int[] increasing(int[] xs){
ArrayList<Integer> current_array = new ArrayList<Integer>();
ArrayList<Integer> list = new ArrayList<Integer>();
int c_counter = 0;
for (int i = 0; i<(xs.length); i++){
if (i==0){
if (xs[i+1] > xs[i]){
current_array.add(xs[i]);
c_counter++; //keeps track of how many elements have been added
}
}
else if ((xs[i] > xs[i-1])){
if (c_counter==0){
current_array.add(xs[i-1]); //makes sure the smaller number gets added too
current_array.add(xs[i]);
c_counter = c_counter + 2;
} else{
current_array.add(xs[i]);
c_counter++;
}
} else {
if (current_array.size()>list.size()){ //compares sizes to find the longest sequence
list.clear();
for (int k=0; k<(current_array.size()); k++){
if (current_array.get(k) != 0){ //removes any null values
list.add(current_array.get(k));
}
}
current_array.clear(); //clears it to restart and find any longer sequences
c_counter = 0;
}
}
}
int[] out_array = list.stream().mapToInt(i->i).toArray(); //converts from arraylist to int[] as that's the format it must output
out_array = list.stream().filter(i->i != null).mapToInt(i->i).toArray();
return out_array;
}
public static int[] increasing(int[] xs){
int start = 0;
int end = 0;
int temp = 0;
for (int i = 0; i < xs.length; i++) {
if(i==0 || xs[i]<xs[i-1]){
temp = i;
}
else if(i-temp > end-start){
start = temp;
end = i;
}
}
return Arrays.copyOfRange(xs, start, end+1);
}
It takes too long time to understand your code. Try this out:
List<Integer> test = new ArrayList<Integer>();
test.add(3);
test.add(2);
test.add(1);
test.add(2);
// test.add(4);
// test.add(6);
// test.add(7);
// test.add(8);
test.add(1);
test.add(2);
test.add(1000);
test.add(97777);
test.add(487);
test.add(8274);
test.add(972837);
List<Integer> output = new ArrayList<Integer>();
List<Integer> temp = new ArrayList<Integer>();
for(int i = 0; i < test.size(); i++) {
int current = test.get(i);
int next = Integer.MIN_VALUE;
if(i + 1 < test.size()) next = test.get(i + 1);
if(current > next) {
if(output.size() <= temp.size()) {
temp.add(current);
output = new ArrayList<Integer>(temp);
}
temp.clear();
} else {
temp.add(current);
}
}
output.forEach(i -> System.out.print(i + ", "));
If you want the longest decreasing output, change int next = Integer.MAX_VALUE; and if(current > next) to if(current < next)

Non-repeating random numbers inside array JAVA

I would like to generate 6 numbers inside an array and at the same time, having it compared so it will not be the same or no repeating numbers. For example, I want to generate 1-2-3-4-5-6 in any order, and most importantly without repeating. So what I thought is to compare current array in generated array one by one and if the number repeats, it will re-run the method and randomize a number again so it will avoid repeating of numbers.
Here is my code:
import javax.swing.*;
public class NonRepeat
{
public static void main(String args[])
{
int Array[] = new int [6];
int login = Integer.parseInt(JOptionPane.showInputDialog("ASD"));
while(login != 0)
{
String output="";
for(int index = 0; index<6; index++)
{
Array[index] = numGen();
for(int loop = 0; loop <6 ; loop++)
{
if(Array[index] == Array[loop])
{
Array[index] = numGen();
}
}
}
for(int index = 0; index<6; index++)
{
output += Array[index] + " ";
}
JOptionPane.showMessageDialog(null, output);
}
}
public static int numGen()
{
int random = (int)(1+Math.random()*6);
return random;
}
}
I've been thinking it for 2 hours and still cant generate 6 numbers without repeating.
Hope my question will be answered.
Btw, Im new in codes so please I just want to compare it using for loop or while loop and if else.
You can generate numbers from, say, 1 to 6 (see below for another solution) then do a Collections.shuffle to shuffle your numbers.
final List<Integer> l = new ArrayList<Integer>();
for (int j = 1; j < 7; j++ ) {
l.add( j );
}
Collections.shuffle( l );
By doing this you'll end up with a randomized list of numbers from 1 to 6 without having twice the same number.
If we decompose the solution, first you have this, which really just create a list of six numbers:
final List<Integer> l = new ArrayList<Integer>();
for (int j = 1; j < 7; j++ ) {
l.add( j );
}
So at this point you have the list 1-2-3-4-5-6 you mentioned in your question. You're guaranteed that these numbers are non-repeating.
Then you simply shuffle / randomize that list by swapping each element at least once with another element. This is what the Collections.shuffle method does.
The solutions that you suggested isn't going to be very efficient: depending on how big your list of numbers is and on your range, you may have a very high probability of having duplicate numbers. In that case constantly re-trying to generate a new list will be slow. Moreover any other solution suggesting to check if the list already contains a number to prevent duplicate or to use a set is going to be slow if you have a long list of consecutive number (say a list of 100 000 numbers from 1 to 100 000): you'd constantly be trying to randomly generate numbers which haven't been generated yet and you'd have more and more collisions as your list of numbers grows.
If you do not want to use Collections.shuffle (for example for learning purpose), you may still want to use the same idea: first create your list of numbers by making sure there aren't any duplicates and then do a for loop which randomly swap two elements of your list. You may want to look at the source code of the Collections.shuffle method which does shuffle in a correct manner.
EDIT It's not very clear what the properties of your "random numbers" have to be. If you don't want them incremental from 1 to 6, you could do something like this:
final Random r = new Random();
final List<Integer> l = new ArrayList<Integer>();
for (int j = 0; j < 6; j++ ) {
final int prev = j == 0 ? 0 : l.get(l.size() - 1);
l.add( prev + 1 + r.nextInt(42) );
}
Collections.shuffle( l );
Note that by changing r.nextInt(42) to r.nextInt(1) you'll effectively get non-repeating numbers from 1 to 6.
You have to check if the number already exist, you could easily do that by putting your numbers in a List, so you have access to the method contains. If you insist on using an array then you could make a loop which checks if the number is already in the array.
Using ArrayList:
ArrayList numbers = new ArrayList();
while(numbers.size() < 6) {
int random = numGen(); //this is your method to return a random int
if(!numbers.contains(random))
numbers.add(random);
}
Using array:
int[] numbers = new int[6];
for (int i = 0; i < numbers.length; i++) {
int random = 0;
/*
* This line executes an empty while until numGen returns a number
* that is not in the array numbers yet, and assigns it to random
*/
while (contains(numbers, random = numGen()))
;
numbers[i] = random;
}
And add this method somewhere as its used in the snippet above
private static boolean contains(int[] numbers, int num) {
for (int i = 0; i < numbers.length; i++) {
if (numbers[i] == num) {
return true;
}
}
return false;
}
Here is the solution according to your code -
You just need to change the numGen method -
public static int numGen(int Array[])
{
int random = (int)(1+Math.random()*6);
for(int loop = 0; loop <Array.length ; loop++)
{
if(Array[loop] == random)
{
return numGen(Array);
}
}
return random;
}
Complete code is -
import javax.swing.*;
public class NonRepeat
{
public static void main(String args[])
{
int login = Integer.parseInt(JOptionPane.showInputDialog("ASD"));
while(login != 0)
{
int Array[] = new int [6];
String output="";
for(int index = 0; index<6; index++)
{
Array[index] = numGen(Array);
}
for(int index = 0; index<6; index++)
{
output += Array[index] + " ";
}
JOptionPane.showMessageDialog(null, output);
}
}
public static int numGen(int Array[])
{
int random = (int)(1+Math.random()*6);
for(int loop = 0; loop <Array.length ; loop++)
{
if(Array[loop] == random)
{
return numGen(Array);
}
}
return random;
}
}
Use List instead of array and List#contains to check if number is repeated.
you can use a boolean in a while loop to identify duplicates and regenerate
int[] array = new int[10]; // array of length 10
Random rand = new Random();
for (int i = 0 ; i < array.length ; i ++ ) {
array[i] = rand.nextInt(20)+1; // random 1-20
boolean found = true;
while (found) {
found = false;
// if we do not find true throughout the loop it will break (no duplicates)
int check = array[i]; // check for duplicate
for (int j = 0 ; j < i ; j ++) {
if ( array[j] == check ) {
found = true; // found duplicate
}
}
if (found) {
array[i] = rand.nextInt(20)+1 ; // replace
}
}
}
System.out.println(Arrays.toString(array));
You may use java.util.Random. And please specify if you want any random number or just the number 1,2,3,4,5,6. If you wish random numbers then , this is a basic code:
import java.util.*;
public class randomnumber
{
public static void main(String[] args)
{
Random abc = new Random();
int[] a = new int[6];
int limit = 100,c=0;
int chk = 0;
boolean y = true;
for(;c < 6;)
{
int x = abc.nextInt(limit+1);
for(int i = 0;i<a.length;i++)
{
if(x==a[i])
{
y=false;
break;
}
}
if(y)
{
if(c!=0)if(x == (a[c-1]+1))continue;
a[c]=x;
c++;
}
}
for (Integer number : a)
{
System.out.println(number);
}
}
}
if you don't understand the last for loop , please tell , i will update it.
Use List and .contains(Object obj) method.
So you can verify if list has the random number add before.
update - based on time you can lost stuck in random loop.
List<Integer> list = new ArrayList<Integer>();
int x = 1;
while(x < 7){
list.add(x);
x++;
}
Collections.shuffle(list);
for (Integer number : list) {
System.out.println(number);
}
http://docs.oracle.com/javase/7/docs/api/java/util/List.html#contains(java.lang.Object)

Given an array with 2 integers that repeat themselves the same no. of times, how do i print the two integers

i'm new to this, Say if you typed 6 6 6 1 4 4 4 in the command line, my code gives the most frequent as only 6 and i need it to print out 6 and 4 and i feel that there should be another loop in my code
public class MostFrequent {
//this method creates an array that calculates the length of an integer typed and returns
//the maximum integer...
public static int freq(final int[] n) {
int maxKey = 0;
//initiates the count to zero
int maxCounts = 0;
//creates the array...
int[] counts = new int[n.length];
for (int i=0; i < n.length; i++) {
for (int j=0; j < n[i].length; j++)
counts[n[i][j]]++;
if (maxCounts < counts[n[i]]) {
maxCounts = counts[n[i]];
maxKey = n[i];
}
}
return maxKey;
}
//method mainly get the argument from the user
public static void main(String[] args) {
int len = args.length;
if (len == 0) {
//System.out.println("Usage: java MostFrequent n1 n2 n3 ...");
return;
}
int[] n = new int[len + 1];
for (int i=0; i<len; i++) {
n[i] = Integer.parseInt(args[i]);
}
System.out.println("Most frequent is "+freq(n));
}
}
Thanks...enter code here
Though this may not be a complete solution, it's a suggestion. If you want to return more than one value, your method should return an array, or better yet, an ArrayList (because you don't know how many frequent numbers there will be). In the method, you can add to the list every number that is the most frequest.
public static ArrayList<Integer> freq(final int[] n) {
ArrayList<Integer> list = new ArrayList<>();
...
if (something)
list.add(thatMostFrequentNumber)
return list;
}
The solutions looks like this:
// To use count sort the length of the array need to be at least as
// large as the maximum number in the list.
int[] counts = new int[MAX_NUM];
for (int i=0; i < n.length; i++)
counts[n[i]]++;
// If your need more than one value return a collection
ArrayList<Integer> mf = new ArrayList<Integer>();
int max = 0;
for (int i = 0; i < MAX_NUM; i++)
if (counts[i] > max)
max = counts[i];
for (int i = 0; i < MAX_NUM; i++)
if (counts[i] == max)
mf.add(i);
return mf;
Well you can just do this easily by using the HashTable class.
Part 1. Figure out the frequency of each number.
You can do this by either a HashTable or just a simple array if your numbers are whole numbrs and have a decent enough upper limit.
Part 2. Find duplicate frequencies.
You can just do a simple for loop to figure out which numbers are repeated more than once and then print them accordingly. This wont necessarily give them to you in order though so you can store the information in the first pass and then print it out accordingly. You can use a HashTable<Integer,ArrayList<Integer> for this. Use the key to store frequency and the ArrayList to store the numbers that fall within that frequency.
You can maintain a "max" here while inserting into our HashTable if you only want to print out only the things with most frequency.
Here is a different way to handle this. First you sort the list, then loop through and keep track of the largest numbers:
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
int n[] = { 6, 4, 6, 4, 6, 4, 1 };
List<Integer> maxNums = new ArrayList<Integer>();
int max = Integer.MIN_VALUE;
Integer lastValue = null;
int currentCount = 0;
Arrays.sort(n);
for( int i : n ){
if( lastValue == null || i != lastValue ){
if( currentCount == max ){
maxNums.add(lastValue);
}
else if( currentCount > max ){
maxNums.clear();
maxNums.add(lastValue);
max = currentCount;
}
lastValue = i;
currentCount = 1;
}
else {
currentCount++;
}
System.out.println("i=" + i + ", currentCount=" + currentCount);
}
if( currentCount == max ){
maxNums.add(lastValue);
}
else if( currentCount >= max ){
maxNums.clear();
maxNums.add(lastValue);
}
System.out.println(maxNums);
}
}
You can try it at: http://ideone.com/UbmoZ5

Categories