I asked a question on helping me with this question about a week ago
Java permutations
, with a problem in the print permutation method. I have tidied up my code and have a working example that now works although if 5 is in the 5th position in the array it doesn't print it. Any help would be really appreciated.
package permutation;
public class Permutation {
static int DEFAULT = 100;
public static void main(String[] args) {
int n = DEFAULT;
if (args.length > 0)
n = Integer.parseInt(args[0]);
int[] OA = new int[n];
for (int i = 0; i < n; i++)
OA[i] = i + 1;
System.out.println("The original array is:");
for (int i = 0; i < OA.length; i++)
System.out.print(OA[i] + " ");
System.out.println();
System.out.println("A permutation of the original array is:");
OA = generateRandomPermutation(n);
printArray(OA);
printPermutation(OA);
}
static int[] generateRandomPermutation(int n)// (a)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
int swap = A[r];
A[r] = A[i];
A[i] = swap;
}
return A;
}
static void printArray(int A[]) {
for (int i = 0; i < A.length; i++)
System.out.print(A[i] + " ");
System.out.println();
}
static void printPermutation(int[] p)
{
int n = p.length-1;
int j = 0;
int m;
int f = 0;
System.out.print("(");
while (f < n) {
m = p[j];
if (m == 0) {
do
f++;
while (p[f] == 0 && f < n);
j = f;
if (f != n)
System.out.print(")(");
}
else {
System.out.print(" " + m);
p[j] = 0;
j = m - 1;
}
}
System.out.print(" )");
}
}
I'm not too crazy about
int n = p.length-1;
followed by
while (f < n) {
So if p is 5 units long, and f starts at 0, then the loop will be from 0 to 3. That would seem to exclude the last element in the array.
You can use the shuffle method of the Collections class
Integer[] arr = new Integer[] { 1, 2, 3, 4, 5 };
List<Integer> arrList = Arrays.asList(arr);
Collections.shuffle(arrList);
System.out.println(arrList);
I don't think swapping each element with a random other element will give a uniform distribution of permutations. Better to select uniformly from the remaining values:
Random rand = new Random();
ArrayList<Integer> remainingValues = new ArrayList<Integer>(n);
for(int i = 0; i < n; i++)
remainingValues.add(i);
for(int i = 0; i < n; i++) {
int next = rand.nextInt(remainingValues.size());
result[i] = remainingValues.remove(next);
}
Note that if order of running-time is a concern, using an ArrayList in this capacity is n-squared time. There are data-structures which could handle this task in n log n time but they are very non-trivial.
This does not answer the problem you have identified.
Rather i think it identifies a mistake with your generateRandomPermutation(int n) proc.
If you add a print out of the random numbers generated (as i did below) and run the proc a few times it allows us to check if all the elements in the ARRAY TO BE permed are being randomly selected.
static int[] generateRandomPermutation(int n)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
System.out.println("random nums generated are: ");
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
System.out.print(r + " ");
Run the proc several times.
Do you see what i see?
Jerry.
Related
public class Bonus1{
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int[] numbers = new int[n];
for (int i = 0; i < n; i++ ) {
numbers[i] = i;
}
for (int i = 0; i < n; i++ ) {
int r = i + (int)(Math.random() * (n - i));
int tmp = numbers[i];
numbers[i] = numbers[r];
numbers[r] = tmp;
System.out.print(numbers[i]);
}
int min = Integer.MAX_VALUE;
int count = 0;
while(data.hasNext()){
int y = data.nextInt();
if(y < min){
min = y;
count += 1;
}
}
System.out.println(count);
}
}
this code isn't complete, the first 2 for-loops will generate an array between 0 to a given number in the commandline -1
So for example java Bonus1 10 would first generate an array between 0-9 and then it will shuffle these numbers around so that it creates a random permutation.
the while loop is something I've used before to read input and determine how many times a new lowest number is detected. so for example if I get the permutation 7 8 2 3 4 5 1 0 6 9 it will count 7 as the lowest, then 2 as the lowest and then 1 as the lowest and finally 0 as the lowest, making the total amount of times a new lowest number has been detected 4.
but this only works if I use inputs, I need to use the previously generated output as the input in the same file, is there a clever way to do that?
You should iterate for the array numbers like this.
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int[] numbers = new int[n];
for (int i = 0; i < n; i++) {
numbers[i] = i;
}
for (int i = 0; i < n; i++) {
int r = i + (int) (Math.random() * (n - i));
int tmp = numbers[i];
numbers[i] = numbers[r];
numbers[r] = tmp;
System.out.print(numbers[i]);
}
System.out.println();
int min = Integer.MAX_VALUE;
int count = 0;
for (int i = 0; i < n; ++i) {
int y = numbers[i];
if (y < min) {
min = y;
++count;
}
}
System.out.println(count);
}
output:
6457098123
3
Here is what I am suppose to be getting.
This is what I am actually getting.
Write a program DiscreteDistribution.java that takes an integer command-line argument m, followed by a sequence of positive integer command-line arguments a1,a2,…,an, and prints m random indices (separated by whitespace), choosing each index i with probability proportional to ai.
So far I have
public static void main(String[] args) {
// number of random indices
int m = Integer.parseInt(args[0]);
// read in frequency of occurrence of n values
int n = args.length;
int[] freq = new int[n];
for (int i = 0; i < n; i++) {
freq[i] = Integer.parseInt(args[i]);
}
// compute total count of all frequencies
int total = 0;
for (int i = 0; i < n; i++) {
total += freq[i];
}
for (int j = 0; j < m; j++) {
// generate random integer with probability proportional to frequency
int r = (int) ((total) * Math.random() - 1); // integer in [0, total)
int sum = 0;
int event = -1;
for (int i = 0; i < n && sum <= r; i++) {
sum += freq[i];
event = i;
System.out.println(freq[i]);
}
}
}
Under the assumption that I understand your problem correctly, then you can use the following algorithm to produce m random numbers in the range 1 to n according to the given frequencies:
public static void main(String[] args) {
// number of random indices
int m = Integer.parseInt(args[0]);
// read in frequency of occurrence of n values
int n = args.length;
int[] freq = new int[n];
for (int i = 1; i < n; i++) {
freq[i] = Integer.parseInt(args[i]);
}
// compute total count of all frequencies
int total = 0;
for (int i = 1; i < n; i++) {
total += freq[i];
}
double[] summedProbabilities = new double[n];
for (int i = 1; i < summedProbabilities.length; i++) {
final double probability = freq[i] / (double) total;
summedProbabilities[i] = summedProbabilities[i -1] + probability;
}
for (int j = 0; j < m; j++) {
// generate random integer with probability proportional to frequency
double randomProbability = Math.random();
int i = 1;
while (randomProbability > summedProbabilities[i]) {
i++;
}
System.out.print(i + " ");
if (j % 10 == 0) {
System.out.println();
}
}
}
I strongly suggest you to refactor the code in a way that you use methods to calculate small pieces and compose it then.
public class DiscreteDistribution{
public static void main(String[] args) {
// takes in number of times we must loop to print indices
int m = Integer.parseInt(args[0]);
// set the array size to the number of input from command line
//minus the first input
//because we are not considering the input at args[0]
int [] n = new int[args.length-1];
// cSum to store the cummulatives
int [] cSum = new int[args.length];
// to store an array of random generated
//number of size m
int [] rand = new int[m];
int count = 1;
int cCount = 1;
int sum = 0; // to add the inputs n;
// to store user input in an array in n ignoring the first input
for(int i =0; i < n.length; i++)
{
n[i] = Integer.parseInt(args[count]);
count++;
}
//stores the cummulatives of n in cSum
for(int j = 0; j < n.length; j++)
{
sum = sum + n[j];
cSum[j+1] = sum;
}
//generate a random number and stores in rand representing the //probabilites
for(int p = 0; p < m; p++) {
int r = (int)(1+Math.random()*cSum[cSum.length-1]);
rand[p] = r;
}
// loop from 0 to m to print the indices of n;
for(int s = 0; s < m; s++) {
//prints the indices corresponding to the condition
for(int q = 1; q < n.length; q++) {
if(rand[s] <= cSum[q-1]) {
System.out.print(q+" ");
}
}
}
}
sorry for my bad english. I'm styding LSD String Sorts algorithm and I have a question related to it. Here my code. I want input W not fixed, for example:
String[] a = {"38A", "3TW723", "2IYEA938", "3CI34780720"};
public static void sort(String[] a, int w) { // Sort a[] on leading W characters.
int R = 256;
int N = a.length;
//For each of the character from right to left
for (int d = w - 1; d >= 0; d--) {
//1. count the frequencies
int[] count = new int[R + 1];
for (int i = 0; i < N; i++) {
count[a[i].charAt(d) + 1]++;
}
//2. Transform counts to indices
for (int r = 0; r < R; r++) {
count[r + 1] += count[r];
}
//3. Distribute
String aux[] = new String[N];
for (int i = 0; i < N; i++) {
aux[count[a[i].charAt(d)]] = a[i];
count[a[i].charAt(d)]++;
}
//4. Copyback
System.arraycopy(aux, 0, a, 0, N);
}
}
To develop an implementation of LSD string sort that works for variable-length strings, we need to do many works on the base of your code. We need to find the longest length of string in string[] a, so when d >= a[i].length(), we return 0, which means we add extra 0 to make every string in the same length. This is my code.
// Develop an implementation of LSD string sort
// that works for variable-length strings.
public class LSDForVariableLengthStrings {
// do not instantiate
private LSDForVariableLengthStrings() { }
// find longest length string in string[] a.
public static int findLongestLength(String[] a) {
int longest = 0;
for (int i = 0; i < a.length; ++i) {
if (a[i].length() > longest) {
longest = a[i].length();
}
}
return longest;
}
// if d >= 0 && d < a[i].length(), return a[i].charAt(d);
// else , return 0, which means least value to sort.
public static int findCharAtInString(int i, int d, String[] a) {
if (d < 0 || d >= a[i].length()) {
return 0;
}
return a[i].charAt(d);
}
// Rearranges the array of variable-length strings.
public static void sort(String[] a) {
int n = a.length;
int R = 256; // extended ASCII alphabet size.
String[] aux = new String[n];
int w = findLongestLength(a); // w is the length of longest string in a.
for (int d = w - 1; d >= 0; d--) {
// sort by key-indexed counting on dth character
// compute frequency counts
int[] count = new int[R + 1];
for (int i = 0; i < n; ++i) {
int c = findCharAtInString(i, d, a);
count[c + 1]++;
}
// compute cumulates
for (int r = 0; r < R; ++r) {
count[r + 1] += count[r];
}
// move data
for (int i = 0; i < n; ++i) {
int c = findCharAtInString(i, d, a);
aux[count[c]++] = a[i];
}
// copy back
for (int i = 0; i < n; ++i) {
a[i] = aux[i];
}
}
}
public static void main(String[] args) {
String[] a = {"38A", "3TW723", "2IYEA938", "3CI34780720"};
int n = a.length;
// sort the strings
sort(a);
// prints results
for (int i = 0; i < n; ++i) {
System.out.println(a[i]);
}
}
}
LSD sorts only fixed-length strings. Use MSD instead
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();
}
}
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)
}
}