public static int[] uniqueRandomElements (int size) {
int[] a = new int[size];
for (int i = 0; i < size; i++) {
a[i] = (int)(Math.random()*10);
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
a[j] = (int)(Math.random()*10);
}
}
}
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
System.out.println();
return a;
}
I have a method above which should generate an array of random elements that the user specifies. The randomly generated integers should be between 0 and 10 inclusive. I am able to generate random integers but the problem I have is checking for uniqueness. My attempt to check for uniqueness is in my code above but the array still contains duplicates of integers. What am I doing wrong and could someone give me a hint?
for (int i = 0; i < size; i++) {
a[i] = (int)(Math.random()*10);
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
a[j] = (int)(Math.random()*10); //What's this! Another random number!
}
}
}
You do find the duplicate values. However, you replace it with another random number that may be a duplicate. Instead, try this:
for (int i = 0; i < size; i++) {
a[i] = (int)(Math.random()*10);//note, this generates numbers from [0,9]
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
i--; //if a[i] is a duplicate of a[j], then run the outer loop on i again
break;
}
}
}
However, this method is inefficient. I recommend making a list of numbers, then randomizing it:
ArrayList<Integer> a = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){ //to generate from 0-10 inclusive.
//For 0-9 inclusive, remove the = on the <=
a.add(i);
}
Collections.shuffle(a);
a = a.sublist(0,4);
//turn into array
Or you could do this:
ArrayList<Integer> list = new ArrayList<>(11);
for (int i = 0; i <= 10; i++){
list.add(i);
}
int[] a = new int[size];
for (int count = 0; count < size; count++){
a[count] = list.remove((int)(Math.random() * list.size()));
}
It might work out faster to start with a sequential array and shuffle it. Then they will all be unique by definition.
Take a look at Random shuffling of an array, and at the Collections.shuffle function.
int [] arr = [1,2,3,.....(size)]; //this is pseudo code
Collections.shuffle(arr);// you probably need to convert it to list first
If you have a duplicate you only regenerate the corresponding number once. But it might create another duplicate. You duplicate checking code should be enclosed in a loop:
while (true) {
boolean need_to_break = true;
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
need_to_break = false; // we might get another conflict
a[j] = (int)(Math.random()*10);
}
}
if (need_to_break) break;
}
But make sure that size is less than 10, otherwise you will get an infinite loop.
Edit: while the above method solves the problem, it is not efficient and should not be used for large sized arrays. Also, this doesn't have a guaranteed upper bound on the number of iterations needed to finish.
A better solution (which unfortunately only solves second point) might be to generate a sequence of the distinct numbers you want to generate (the 10 numbers), randomly permute this sequence and then select only the first size elements of that sequence and copy them to your array. You'll trade some space for a guarantee on the time bounds.
int max_number = 10;
int[] all_numbers = new int[max_number];
for (int i = 0; i < max_number; i++)
all_numbers[i] = i;
/* randomly permute the sequence */
for (int i = max_number - 1; i >= 0; i--) {
int j = (int)(Math.random() * i); /* pick a random number up to i */
/* interchange the last element with the picked-up index */
int tmp = all_numbers[j];
all_numbers[j] = a[i];
all_numbers[i] = tmp;
}
/* get the a array */
for (int i = 0; i < size; i++)
a[i] = all_numbers[i];
Or, you can create an ArrayList with the same numbers and instead of the middle loop you can call Collections.shuffle() on it. Then you'd still need the third loop to get elements into a.
If you just don't want to pay for the added overhead to ArrayList, you can just use an array and use Knuth shuffle:
public Integer[] generateUnsortedIntegerArray(int numElements){
// Generate an array of integers
Integer[] randomInts = new Integer[numElements];
for(int i = 0; i < numElements; ++i){
randomInts[i] = i;
}
// Do the Knuth shuffle
for(int i = 0; i < numElements; ++i){
int randomIndex = (int)Math.floor(Math.random() * (i + 1));
Integer temp = randomInts[i];
randomInts[i] = randomInts[randomIndex];
randomInts[randomIndex] = temp;
}
return randomInts;
}
The above code produces numElements consecutive integers, without duplication in a uniformly random shuffled order.
import java.util.Scanner;
class Unique
{
public static void main(String[]args)
{
int i,j;
Scanner in=new Scanner(System.in);
int[] a=new int[10];
System.out.println("Here's a unique no.!!!!!!");
for(i=0;i<10;i++)
{
a[i]=(int)(Math.random()*10);
for(j=0;j<i;j++)
{
if(a[i]==a[j])
{
i--;
}
}
}
for(i=0;i<10;i++)
{
System.out.print(a[i]);
}
}
}
Input your size and get list of random unique numbers using Collections.
public static ArrayList<Integer> noRepeatShuffleList(int size) {
ArrayList<Integer> arr = new ArrayList<>();
for (int i = 0; i < size; i++) {
arr.add(i);
}
Collections.shuffle(arr);
return arr;
}
Elaborating Karthik's answer.
int[] a = new int[20];
for (int i = 0; i < size; i++) {
a[i] = (int) (Math.random() * 20);
for (int j = 0; j < i; j++) {
if (a[i] == a[j]) {
a[i] = (int) (Math.random() * 20); //What's this! Another random number!
i--;
break;
}
}
}
int[] a = new int [size];
for (int i = 0; i < size; i++)
{
a[i] = (int)(Math.random()*16); //numbers from 0-15
for (int j = 0; j < i; j++)
{
//Instead of the if, while verifies that all the elements are different with the help of j=0
while (a[i] == a[j])
{
a[i] = (int)(Math.random()*16); //numbers from 0-15
j=0;
}
}
}
for (int i = 0; i < a.length; i++)
{
System.out.println(i + ". " + a[i]);
}
//Initialize array with 9 elements
int [] myArr = new int [9];
//Creating new ArrayList of size 9
//and fill it with number from 1 to 9
ArrayList<Integer> myArrayList = new ArrayList<>(9);
for (int i = 0; i < 9; i++) {
myArrayList.add(i + 1);
}
//Using Collections, I shuffle my arrayList
Collections.shuffle(myArrayList);
//With for loop and method get() of ArrayList
//I fill my array
for(int i = 0; i < myArrayList.size(); i++){
myArr[i] = myArrayList.get(i);
}
//printing out my array
for(int i = 0; i < myArr.length; i++){
System.out.print(myArr[i] + " ");
}
You can try this solution:
public static int[] uniqueRandomElements(int size) {
List<Integer> numbers = IntStream.rangeClosed(0, size).boxed().collect(Collectors.toList());
return Collections.shuffle(numbers);
}
Related
I had an assignment to create an array of random number from 10-100.
Then I need to sout all the numbers not listed in the array.
I did the assignment with a nested for loops, to cross reference the arrays, then I changed all the found numbers in the array into -1. Finally I printed out the elements in the array that were not -1.
My professor told me that is it possible for me to do this assignment with only one for loop and there is no need to do a nested for loop. and make the computer run 10,000 times instead of just 100.
Is that possible? If so how?
Thank you.
package assignment.pkg1;
import java.util.Random;
public class Assignment1 {
static Random ran = new Random();
public static void main(String[] args) {
int[] arr = new int[100];
for (int i = 0; i < 100; i++) {
arr[i] = (ran.nextInt(90)) + 10;
}
InversingArray(arr);
}
public static void InversingArray(int[] randomArray) {
int[] fullArray = new int[100];
for (int i = 0; i < 100; i++) {
fullArray[i] = i;
}
for (int i = 0; i < 100; i++) {
for (int j = 1; j < 100; j++) {
if (randomArray[j] == fullArray[i]) {
fullArray[i] = -1;
}
}
}
System.out.println("These numbers are not in randomArray: ");
for (int i = 0; i < 100; i++) {
if (fullArray[i] != -1) {
System.out.println(fullArray[i]);
}
}
}
In your code you create an array to hold the possible values. If you think about it, the array index will always be equal to the number stored in the array.
fullArray[i] = i;
This is redundant.
What you are being asked to do is determine which numbers have been used: a boolean test. This means that you should have an array of boolean that is initially false (the default value of booleans in java) and is flipped to true when an equal integer is flipped to true.
Something like
int[] arr = new int[100];
for (int i = 0; i < 100; i++) {
arr[i] = (ran.nextInt(90)) + 10;
}
// ba starts with all false values
boolean ba[] == new boolean[90]; // note that the instructor said 10-100
for(int i=0; i<90; i++) {
ba[arr[i]] = true;
// lets assume arr[0] == 45
// ba[arr[0]] is the same as ba[45]
// ba[45] = true; will set that bucket of the boolean array to true
}
System.out.println("These numbers are not in randomArray: ");
for (int k = 0; k < 10; k++) {
System.out.println(k);
}
for (int j = 0; j < 90; j++) {
if (!ba[j]) { // shorthand for ba[j]==false
System.out.println(j+10); // The array starts at a base of 10
}
}
Be aware (probably the point of the exercise) that you are working with an array [0..90] that represents the numbers [10..100].
The nested loop currently looks like this:
for (int i = 0; i < 100; i++) {
for (int j = 1; j < 100; j++) {
if (randomArray[j] == fullArray[i]) {
fullArray[i] = -1;
}
}
}
But we know, that fullArray[i] is always the same as i.
So you can rewrite it to:
for (int j = 1; j < 100; j++) {
int i = randomArray[j];
fullArray[i] = -1;
}
Or even shorter:
for (int j = 1; j < 100; j++) {
fullArray[randomArray[j]] = -1;
}
i have taken 10 inputs and my program works perfectly but as i start taking large number of inputs like 100,1000 my programs does not work and get an error or generally it stops working.
So how can i solve it please give me solution.
Below is the code i have written:
package PROGARMS;
import java.util.Random;
import java.util.Scanner;
public class Radix1 {
public static void main(String[] args){
int i,j,k=0,x=10,m=0,n;
Scanner k1=new Scanner(System.in);
Random r=new Random();
System.out.println("enter number of elements u want to sort");
n=k1.nextInt();
int[] a=new int[n];
for(i=0;i<n;i++)
{
a[i]=r.nextInt(10000);
}
n=a.length;
System.out.println("Array before sorting");
for(i=0;i<n;i++)
System.out.println(a[i]+" ");
System.out.println();
int[] b=new int[n];
int[] z=new int[n];
int max=a[0];
for(i=1;i<n;i++)
{
if(max<a[i])
max=a[i];
}
int length=0;
while(max!=0)
{
length++;
max=max/10;
}
//length=1;
System.out.println("length="+length);
while(m<length){
System.out.println("x="+x);
for(i=0;i<n;i++)
{
b[i]=a[i]%x;
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(b[i]<b[j])
{
int key=b[i];
b[i]=b[j];
b[j]=key;
}
}
}
for(int s=0;s<n;s++)
System.out.println("s="+s+",b[s]="+b[s]);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(b[i]==a[j]%x)
{
if(k>=n)
{
System.out.println("k is greater,M="+m);
k=0;
}
//ystem.out.println("k="+k+",j="+j);
z[k]=a[j];
a[j]=0;
k++;
}
}
}
for(int s=0;s<n;s++)
a[s]=z[s];
//for(int s=0;s<n;s++)
//System.out.println("s="+s+",a[s]="+a[s]);
m++;
x=x*10;
k=0;
System.out.println();
}
System.out.println("After sorting Final result");
for(int s=0;s<n;s++)
System.out.println("s="+s+",a[s]="+a[s]);
}
}
I think I've got it: In your main sort loop, when you're moving the values from a across to z, you remove them from a after you're done. That's fine, except you 'remove' them by setting them to 0:
a[j]=0;
Thing is, 0 is a valid value, so if your loop is looking for values with a 0 in this place, this does not remove it from consideration. This shows up as k overrunning the array, which triggers the k is greater,M= message, but this is swallowed and the program continues.
You can fix this by setting a[j] to a value it couldn't possibly be:
a[j]=-1;
This then can't be double-counted, and the bug disappears.
I've written this change and changed the guard condition to throw an exception below. I've also added some comments for readability, and some changes to the logging which made it more readable for me (although your taste may vary).
import java.util.Random;
import java.util.Scanner;
public class RadixSort {
public static void main(String[] args) {
int i, j, k = 0, x = 10, m = 0, n;
Random r = new Random();
Scanner k1 = new Scanner(System.in);
System.out.println("Enter number of elements you want to sort");
n = k1.nextInt();
// Choose random numbers to sort
int[] a = new int[n];
for (i = 0; i < n; i++) {
a[i] = r.nextInt(10000);
}
// Print initial array
System.out.println("Array before sorting");
for (i = 0; i < n; i++)
System.out.print(a[i] + " ");
System.out.println();
// Find the largest value
int max = a[0];
for (i = 1; i < n; i++) {
if (max < a[i])
max = a[i];
}
// Find the (decimal) length of the longest value
int length = 0;
while (max != 0) {
length++;
max = max / 10;
}
System.out.println("length=" + length);
// Main sort loop
int[] b = new int[n];
int[] z = new int[n];
while (m < length) {
// Place being sorted
System.out.println("x=" + x);
// `b` is a copy of `a` including only the digit to be sorted in this pass
for (i = 0; i < n; i++) {
b[i] = a[i] % x;
}
// Bubble sort `b`
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
if (b[i] < b[j]) {
int key = b[i];
b[i] = b[j];
b[j] = key;
}
}
}
// Print out the sorted `b` array
for (int s = 0; s < n; s++)
System.out.print(b[s]+",");
System.out.println();
// Apply the sort from `b` to `a`.
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
// If the ith entry in `a` has the same digit as `b`, move it across
if (b[i] == a[j] % x) {
// XXX: Some kind of loop guard? This indicates an error, and should exit.
if (k >= n) {
throw new IllegalStateException("k is greater than n, when M=" + m);
}
// Move the jth value out of `a` into a temporary buffer `z`.
z[k] = a[j];
// XXX: Problem is, '0' is a valid value.
a[j] = -1;
k++;
}
}
}
// Transcribe the sorted array back into `a`
for (int s = 0; s < n; s++)
a[s] = z[s];
// Move on to the next digit.
m++;
x = x * 10;
k = 0;
}
// Print the final result
System.out.println("After sorting Final result");
for (int s = 0; s < n; s++)
System.out.print(a[s]+",");
System.out.println();
}
}
I am new with Java.
I try to do one of my assignment, but i can not figure out why my result still can not sort.
I have a prompt value(argument) 20 10 30 60 55, and i want to sort it.
I wrote two loops, and converted prompt value (which is string) to Integer.
Result: ( It is not sorted)
20
10
30
60
55
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 5
at question2.SortedArray.main(SortedArray.java:29)
This is the code i wrote:
int temp = 0;
int array[] = null;
int array2[];
for(int i=0; i<args.length; i++){
int a = Integer.parseInt(args[i]);
array = new int[a];
for(int j=0; j<args.length; j++){
int b = Integer.parseInt(args[i]);
array2 = new int[b];
if(array[i]>array2[j])
temp = array2[j];
array2[j] = array[i];
array[i] = temp;
}
}
for (int i = 0; i < array.length; i++)
{
System.out.println(args[i].toString());
}
I could understand this code i fould online below
int tempVar;
for (int i = 0; i < numbers.length; i++)
{
for(int j = 0; j < numbers.length; j++)
{
if(numbers[i] > numbers[j])
{
tempVar = numbers [j ];
numbers [j]= numbers [i];
numbers [i] = tempVar;
}
}
}
for (int i = 0; i < numbers.length; i++)
{
System.out.print(numbers[i]+" ");
}
}
First, convert the String array of args into an int array of values. Then sort and display values. You've been sorting arrays (sized by your array int value), then printing the arguments (which you didn't sort). So, something like
int[] values = new int[args.length];
for (int i = 0; i < args.length; i++) {
values[i] = Integer.parseInt(args[i]);
}
int temp = 0;
for (int i = 0; i < values.length - 1; i++) {
for (int j = i + 1; j < values.length; j++) {
if (values[i] > values[j]) {
temp = values[j];
values[j] = values[i];
values[i] = temp;
}
}
}
System.out.println(Arrays.toString(values));
You need to initialize your array to hold your prompt values
int [] yourArray = {2,3,4 5,};
You don't need a second array to sort the values just a temporary int to hold the value that is being moved.
The statements below if needs to be enclose with { } otherwise all it will do is run to the first semicolon and then get out of the if.
Basically what the code you pasted in the second part is checking if element at the value i is greater than the value at element j. If the value is greater it swaps j with i.
for (int i = 0; i < numbers.length; i++)
{
for(int j = 0; j < numbers.length; j++)
{
if(numbers[i] > numbers[j]) //if element at i is greater than element a j
{
tempVar = numbers [j ]; //store the number at element j in temp
numbers [j]= numbers [i];// set the number at element i to element j
numbers [i] = tempVar;// set the number at temp to element
}
} // does this for each element until no element i greater than j
}
Get the integers to an array at first.
int[] yourArray = { 20, 10, 30, 60, 55 };
for (int i = 0; i < yourArray.length; i++) {
for (int j = 0; j < yourArray.length - 1; j++) {
// swap
if (yourArray[i] < yourArray[j]) {
int temp = yourArray[i];
yourArray[i] = yourArray[j];
yourArray[j] = temp;
}
}
}
for (int i : yourArray)
System.out.println(i);
Output
10
20
30
55
60
This was assignment 1.
Now I have to create the same thing but use a random array of 1-100 values and i have no clue how implement that into what i already have.
public class Test {
public static void main(String a[]) {
int i;
int[] array = {9,1,5,8,7,2,1,5,5,6,8,15,3,9,19,18,88,10,1,100,4,8};
System.out.println("Values Before the sort:\n");
for (i = 0; i < array.length; i++)
System.out.print(array[i] + " ");
System.out.println();
bubble_srt(array, array.length);
System.out.print("Values after the sort:\n");
for (i = 0; i < array.length; i++)
System.out.print(array[i] + " ");
System.out.println();
}
public static void bubble_srt(int a[], int n) {
int i, j, t = 0;
for (i = 0; i < n; i++) {
for (j = 1; j < (n - i); j++) {
if (a[j - 1] > a[j]) {
t = a[j - 1];
a[j - 1] = a[j];
a[j] = t;
}
}
}
}
You need to use a random generator to get the numbers.
For an array of size X it would be something like this:
int[] array = new int[X];
Random random = new Random();
for (int i = 0; i < X; i++)
array[i] = random.nextInt(100) + 1;
You should take a look at the documentation for Random.
I'll echo what Jim has said in the comments. Being resourceful is an important skill as a software developer. A Google search would have quickly turned up a helpful article like this one.
You need to use the Random class to accomplish this.
Random randomGenerator = new Random();
int array = new int[100];
for (int idx = 0; idx < 100; ++idx){
array[idx] = randomGenerator.nextInt(100) + 1;
}
Note on the usage of the nextInt(int n) method:
It produces a pseudo-random integer between 0 (inclusive) and the specified integer (exclusive). That is the reason for adding 1 to the output of nextInt(100) as it shifts your output range from 0-99 to 1-100 as desired.
public void generateRandom()
{
int[] x = new int[100]; // This initializes an array of length 100
Random rand = new Random();
for(int i = 0; i < 100; i++)
{
x[i] = rand.nextInt(100); // Use the random class to generate random integers (and give boundaries)
}
}
This question already has answers here:
Java: Manipulating an Array
(5 answers)
Closed 9 years ago.
I understand how to sort an array by ascending and descending order, but there is a specific pattern I'm trying to create. For example, I have an array in a random order. How would I sort this array in the pattern? "smallest, largest, second smallest, second largest, thrid smallest, third largest..." etc Any ideas?
public class Test2 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int[] array = {1,4,2,6,9,3,65,77,33,22};
for(int i = 0; i < array.length; i++){
System.out.print(" " + array[i]);
}
wackySort(array);
}
public static void wackySort(int[] nums){
int sign = 0;
int temp = 0;
int temp2 = 0;
//This sorts the array
for (int i = 0; i < nums.length; i++){
for (int j = 0; j < nums.length -1; j++){
if (nums[j] > nums[j+1]){
temp = nums[j];
nums[j] = nums[j+1];
nums[j+1] = temp;
}
}
}
// This prints out the new array
System.out.println();
for(int i = 0; i < nums.length; i++){
System.out.print(" " + nums[i]);
}
System.out.println();
//This part attempts to fix the array into the order I want it to
int firstPointer = 0;
int secondPointer = nums.length -1;
int[] newarray = new int[nums.length];
for (int i = 0; i < nums.length -1; i+=2){
newarray[i] = nums[firstPointer++];
newarray[i] = nums[secondPointer--];
}
for(int i = 0; i < newarray.length; i++){
System.out.print(" " + newarray[i]);
}
}
}
You need to write your own Comparator to achieve this. Study this article about Java Object Sorting Example (Comparable And Comparator). it will be helpful to you.