As I learn Algorithms Book authoried by Robert Sedgewick,when I complete the Selection.java code , I find that there is no output,I hardly know why.
Below is my code.
import java.util.Comparator;
import edu.princeton.cs.algs4.StdIn;
import edu.princeton.cs.algs4.StdOut;
public class Selection {
public static void sort(Comparable[] a) {
int n = a.length;
for (int i = 0; i < n; i++) {
int min = i;
for (int j = i + 1; j < n; j++)
if (less(a[j], a[min]))
min = j;
exch(a, i, min);
}
}
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
private static boolean less(Comparator comparator, Object v, Object w) {
return comparator.compare(v, w) < 0;
}
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
/***************************************************************************
* Check if array is sorted - useful for debugging.
***************************************************************************/
// is the array a[] sorted?
private static boolean isSorted(Comparable[] a) {
return isSorted(a, 0, a.length - 1);
}
// is the array sorted from a[lo] to a[hi]
private static boolean isSorted(Comparable[] a, int lo, int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i - 1]))
return false;
return true;
}
// is the array a[] sorted?
private static boolean isSorted(Object[] a, Comparator comparator) {
return isSorted(a, comparator, 0, a.length - 1);
}
// is the array sorted from a[lo] to a[hi]
private static boolean isSorted(Object[] a, Comparator comparator, int lo,
int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(comparator, a[i], a[i - 1]))
return false;
return true;
}
// print array to standard output
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
StdOut.println(a[i]);
}
}
public static void main(String[] args) {
String[] a = StdIn.readAllStrings();
// Selection.sort(a);
show(a);
}
}
And then is my two test
1.http://algs4.cs.princeton.edu/21elementary/tiny.txt
S O R T E X A M P L E
2.http://algs4.cs.princeton.edu/21elementary/words3.txt
bed bug dad yes zoo
now for tip ilk dim
tag jot sob nob sky
hut men egg few jay
owl joy rap gig wee
was wad fee tap tar
dug jam all bad yet
I expect the increasing order in the output,but there is no output.
And I set the Run Configuration--Commman Tab --Input File as ~/tiny.txt
But when I apply and run,there is no output(I use Eclipse Mars 4)
Then I guess maybe the parameter or type Comparable,Because there is a lot warning of it,but I can't handle it.
Anyone could tell me how to solve the problem:)
edu.princeton.cs.algs4.StdOut internally uses PrintWriter initialized as out = new PrintWriter(new OutputStreamWriter(System.out, CHARSET_NAME), true);. The println methods just write to the stream, but does not flush. You may either do:
StdOut.print() at the end of your writing which intern calls out.flush()
StdOut.print(Object o) method which always calls flush()
Reference: StdOut.java
Related
I've implemented the Heap's algorithm for finding all permutations of the elements of array A:
//A = {1, 2, 3, 4}; B = perms(A) ; num_row(B) = (4!+1) and B[0][0] = 4!;
//This is B.R. Heap's algorithm
public static void perms(int [] A, int [][]B, int n)
{
if (n == 1)
{
int k = B[0][0];
for (int i = 0; i < A.length; i++)
{
B[k + 1][i] = A[i];
}
B[0][0]++;
}
else
{
for (int i = 0; i < n - 1 ;i++)
{
perms(A, B, n-1);
if (n % 2 == 0)
{
swap(A, i, n - 1);
}
else
{
swap(A, 0, n - 1);
}
}
perms(A, B, n - 1);
}
}
public static void swap(int[] A, int i, int j)
{
int temp = A[i];
A[i] = A[j];
A[j] = temp;
}
I'm new to Java. The problem is I want to have B as the output (return) of the function perms(A) , but in this implementation, I have to initialize a int[n! + 1][A.length] B array before calling the function. How can I do it?
Is there anything like private variable or anything in java to help a recursive function to remember a variable from a former call?
Thanks
You can create an "entering" method to recursion like this:
public static int[][] perms(int[] a){
int[][] perms = new int[factorial(a.length)+1][a.length];
perms(a,perms,a.length);
return perms;
}
Method factorial is well know method and can be found on Google for example
Wondering if n parameter is neccessary
EDIT
it is not neccessary (above corrected)
EDIT
By my test the k variable is just incrementing, so I would use static variable like this:
private static int counter = 0;
// your code here, following is a part of your perms method
if (n == 1)
{
for (int i = 0; i < A.length; i++)
{
B[counter][i] = A[i];
}
counter++;
}
//and my code corrected too:
public static int[][] perms(int[] a){
int[][] perms = new int[factorial(a.length)][a.length]; //+1 is not necessary
counter=0; //necessary to call it again
perms(a,perms,a.length);
return perms;
}
I wrote a program for this problem:
“Write a program that, given an array array[] of n numbers and another number x, determines whether or not there exist two elements in array whose sum is exactly x.”
Which is this:
boolean hasArrayTwoCandidates (int array[], int sum) {
int length = array.length;
quickSort(array, 0, length-1);
int first, last;
first = 0;
last = length-1;
while(first < last){
if( array[first] + array[last] == sum )
return true;
else if( array[first] + array[last] < sum )
first++;
else // array[i] + array[j] > sum
last--;
}
return false;
}
At first place, I don't know where should I put or add "quick sort" codes. I have this problem with other programs, as well; when I want to add written methods to the present one.
Should I create a "new class" under this "project" and put "quicksort" codes there?
Should I put them in this class? but how can I use it?
At second place, I don't know what should I write in my "main method"?
this is my quicksort codes:
public void sort(int[] values) {
if (values == null || values.length == 0){
return;
}
this.array = values;
length = values.length;
quickSort(this.array, 0, length - 1);
}
private void quickSort(int[] array, int low, int high) {
int i = low, j = high;
int pivot = array[low + (high-low)/2];
while (i <= j) {
while (array[i] < pivot) {
i++;
}
while (array[j] > pivot) {
j--;
}
if (i <= j) {
exchange(i, j);
i++;
j--;
}
}
if (low < j)
quickSort(array, low, j);
if (i < high)
quickSort(array, i, high);
}
private void exchange(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
actually, I dont know what should I write in my "main method" to run this program?
For you Question you can do simply this kind of coding in main method:
public static void main(String[]args) {
int x = 20;
int[] arr = {2,5,4,10,12,5};
System.out.println(hasArrayTwoCandidates(arr,x));
}
make the methods static
static boolean hasArrayTwoCandidates (int array[], int sum)
But there are porblems in your coding:
private void exchange(int i, int j) {
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
Here the array is not defined. you'll get an error. you have to pass the array too to the method make it as.
private void exchange(int i, int j,int[] array)
But since you are not necessary to do sorting. I recommend this.
static boolean hasArrayTwoCandidates (int array[], int sum) {
boolean flag = false;
for(int i=0;i<array.length-1;i++){
for(int j=i+1;j<array.length ;j++){
if(array[i]+array[j] == sum)
flag = true;
}
}
return flag;
}
this will get one element and check while adding other elements that it is true
Then the main method come same way.
you can put all those method in same class, make hasArrayTwoCandidates() static (Note that main method is static and a static method can have access only to static methods)
public static boolean hasArrayTwoCandidates (int array[], int sum) {
....
}
and in your main method you can test it like this :
public static void main(String[] args){
int[] arr = {2,5,12,5,2,7,15};
System.out.print(hasArrayTwoCandidates(arr, 27));
}
Answering your questions: you can write methods and call them within the same class, just write them with the static modifier:
private static <return_type> <methodName> (<type> param1, <type> param2) {
// Your code here
}
For a program like this, I don't get why you are thinking about sorting the array before checking the sum of 2 numbers within it, when you could do all at once. Check out this code, this may shine a light on you. It is straight-forward and only to see if it clarifies your logic.
import java.util.Random;
public class VerifySum {
public static void main(String[] args) {
Random rand = new Random();
int[] array = new int[10];
// Produce a random number from 10 to 20
int randomSum = rand.nextInt(11) + 10;
// Fill out the array with random integers from 0 to 10
for (int i = 0; i < array.length; i++) {
array[i] = rand.nextInt(11);
}
// Check all array indexes against each other
for (int i = 0; i < array.length - 1; i++) {
for (int j = i + 1; j < array.length; j++) {
if (array[i] + array[j] == randomSum) {
System.out.println(array[i] + " + " + array[j] + " = " + randomSum);
}
}
}
// Print "x"
System.out.println("randomSum = " + randomSum);
// Print array for verification of the functionality
for (int i = 0; i < array.length; i++) {
System.out.println("array [" + i + "] = " + array[i]);
}
}
}
Sometimes making it simpler is more efficient. ;-)
I am giving a time interval in the form of two arrays.
A[0]= 2 B[0]=3
A[1]= 9 B[1]=11
A[2] = 5 B[2]=6
A[3] = 3 B[3]=10
I want to sort the interval on the basics of starting time i.e.
(2,3) , (3,10) ,(5,6) ,(9,11)
Does i have to make a structure of this. or it can be done straight.
Try:
private static class StartEnd implements Comparable<StartEnd> {
private final int start;
private final int end;
// + constructor + getters
#Override
public int compareTo(StartEnd other) {
return start - other.getStart();
}
}
public void sort(int[] starts, int[] ends) {
StartEnd[] ses = new StartEnd[starts.length];
for(int i = 0 ; i < starts.length ; ++i) {
ses[i] = new StartEnd(starts[i], ends[i]);
}
Arrays.sort(sis);
// re-insert
for(int i = 0 ; i < ses.length ; ++i) {
starts[i] = ses[i].getStart;
ends[i] = ses[i].getEnd();
}
}
It can be done straight, since you dont show what have you tried so far I just give you the algorithm:
for j = 1 to n
for i = i+1 to n
if(A[i]>A[j]){
swap(A[i],A[j])
swap(B[i],B[j])
}
you can easily convert it to java code.
this algorithm is buble sort if you want better algorithm use this wiki link to improve your time.
As DwB want here is merge sort full java code that do what you want. I got merge sort algorithm from here and modify to satisfy your need. also you could see the working version on Ideone
Merge Sort:
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
private int[] A;
private int[] B;
private int[] helperA;
private int[] helperB;
private int length;
public static void main (String[] args){
int[] As = {2,9,5,3};
int[] Bs = {3,11,6,10};
new Ideone().sort(As,Bs);
}
public void sort(int[] As , int[] Bs) {
A = As;
B = Bs;
length = A.length;
this.helperA = new int[length];
this.helperB = new int[length];
mergesort(0, length - 1);
for(int i = 0 ; i<length ; i++)
System.out.println("(" + A[i] + "," + B[i]+ ")");
}
private void mergesort(int low, int high) {
// check if low issmaller then high, if not then the array is sorted
if (low < high) {
// Get the index of the element which is in the middle
int middle = low + (high - low) / 2;
// Sort the left side of the array
mergesort(low, middle);
// Sort the right side of the array
mergesort(middle + 1, high);
// Combine them both
merge(low, middle, high);
}
}
private void merge(int low, int middle, int high) {
// Copy both parts into the helper array
for (int i = low; i <= high; i++) {
helperA[i] = A[i];
helperB[i] = B[i];
}
int i = low;
int j = middle + 1;
int k = low;
// Copy the smallest values from either the left or the right side back
// to the original array
while (i <= middle && j <= high) {
if (helperA[i] <= helperA[j]) {
A[k] = helperA[i];
B[k] = helperB[i];
i++;
} else {
A[k] = helperA[j];
B[k] = helperB[j];
j++;
}
k++;
}
// Copy the rest of the left side of the array into the target array
while (i <= middle) {
A[k] = helperA[i];
B[k] = helperB[i];
k++;
i++;
}
}
}
Step 1: Java is an object oriented language; learn to use objects.
Possible class for the time interval
public class TimeInterval implements Comparable<TimeInterval>
{
private int end;
private int start;
public TimeInterval(
final int end,
final int start)
{
this.end = end;
this.start = start;
}
public int getEnd()
{
return end;
}
public int getStart()
{
return start;
}
public int comareTo(final TimeInterval other)
{
if (other == null)
{
return -1; // this will put the null value objects at the end.
}
return start - other.start;
}
}
The classical Javanese "object oriented" approach for this is to use a dedicated class storing a pair of values (int values, in this case), and sort them, as already pointed out in most of the other answers. However, I'd recommend to not make this class Comparable. Instead, a Comparator could be used, which would make it much easier to introduce new sorting orders. Particularly, there could be Comparator implementations for sorting in ascending/descending order, based on the first/second value, respectively. Only then, object orientation plays out its advantages, compensating the "disadvantage" of having to create such a pair of int values as a "dummy data structure" in the first place...
However, I wanted to try to find a solution for the original question as well, namely, sorting two arrays "in sync". Despite the task of sorting seemingly being trivial, one can dedicate a lot of work to doing it right (see Chapter 3 of TAOCP). A bubble sort is simple but inefficient even for medium-sized arrays. Implementing a quick- or merge sort can be fiddly when trying to get the indices right. However, one solution can be obtained by simply taking the existing sort method from java.lang.Arrays, and factoring out the most elementary building block: The swap function:
public class ArraySort
{
public static void main(String[] args)
{
final int A[] = new int[4];
final int B[] = new int[4];
A[0] = 2; B[0] = 3;
A[1] = 9; B[1] = 11;
A[2] = 5; B[2] = 6;
A[3] = 3; B[3] = 10;
Swapper swapper = new Swapper()
{
#Override
public void swap(int array[], int i0, int i1)
{
ArraySort.swap(A, i0, i1);
ArraySort.swap(B, i0, i1);
}
};
sort(A, 0, A.length, swapper);
for (int i=0; i<A.length; i++)
{
System.out.println("("+A[i]+","+B[i]+")");
}
}
interface Swapper
{
void swap(int array[], int i0, int i1);
}
public static void swap(int array[], int i0, int i1)
{
int t = array[i0];
array[i0] = array[i1];
array[i1] = t;
}
// The following methods are copied from java.util.Arrays:
public static void sort(int x[], int off, int len, Swapper swapper)
{
if (len < 7)
{
for (int i = off; i < len + off; i++)
{
for (int j = i; j > off && x[j - 1] > x[j]; j--)
{
swapper.swap(x, j, j - 1);
}
}
return;
}
int m = off + (len >> 1);
if (len > 7)
{
int l = off;
int n = off + len - 1;
if (len > 40)
{
int s = len / 8;
l = med3(x, l, l + s, l + 2 * s);
m = med3(x, m - s, m, m + s);
n = med3(x, n - 2 * s, n - s, n);
}
m = med3(x, l, m, n);
}
int v = x[m];
int a = off, b = a, c = off + len - 1, d = c;
while (true)
{
while (b <= c && x[b] <= v)
{
if (x[b] == v)
{
swapper.swap(x, a++, b);
}
b++;
}
while (c >= b && x[c] >= v)
{
if (x[c] == v)
{
swapper.swap(x, c, d--);
}
c--;
}
if (b > c)
{
break;
}
swapper.swap(x, b++, c--);
}
int s, n = off + len;
s = Math.min(a - off, b - a);
vecswap(x, off, b - s, s, swapper);
s = Math.min(d - c, n - d - 1);
vecswap(x, b, n - s, s, swapper);
if ((s = b - a) > 1)
{
sort(x, off, s, swapper);
}
if ((s = d - c) > 1)
{
sort(x, n - s, s, swapper);
}
}
private static void vecswap(int x[], int a, int b, int n, Swapper swapper)
{
for (int i = 0; i < n; i++, a++, b++)
{
swapper.swap(x, a, b);
}
}
private static int med3(int x[], int a, int b, int c)
{
return (x[a] < x[b] ? (x[b] < x[c] ? b : x[a] < x[c] ? c : a)
: (x[b] > x[c] ? b : x[a] > x[c] ? c : a));
}
}
Notes
This is not a solution that I would recommend. It's just an attempt to answer the question
or it can be done straight. [sic!]
And the answer is: Yes, it is possible, although the solutions that are introducing some sort of an IntPair are more idiomatic.
Apart from that, it would probably be more efficient to "inline" the Swapper#swap calls to directly swap elements of two arrays that are stored in instance variables, or passed as method parameters. However, I liked the genericity of such a Swapper interface. Additionally, it would be nice to generalize this even further, by passing in something like a
interface IntArrayEntryComparator {
int compare(int array[], int i0, int i1);
}
But the latter would go beyond what I wanted to test/demonstrate with this class.
instead having two arrays, create object which holds your intervals
class Interval implements Comparable<Interval> {
private Long start,completed
public Interval(Long start, Long completed) {
this.start = start;
this.completed = completed;
}
#Override
public int compareTo(Interval o) {
return start.compareTo(o.start);
}
//getters and setters ommited
}
then, all what you need to do is implement compareTo method and put all your data in some collection ie List<Interval> intervals
and used Collections.sort(intervals) to sort them
EDIT
Example:
originally you have:
A[0]= 2 B[0]=3,
A[1]= 9 B[1]=11
A[2] = 5 B[2]=6
A[3] = 3 B[3]=10`
lets replace this by:
List<Interval> intervals = new ArrayList<>();
intervals.add(new Interval(2L,3L));
intervals.add(new Interval(9L,11L));
intervals.add(new Interval(5L,6L));
intervals.add(new Interval(3L,10L));
//NOTE L is added at the end variable as interval uses Long, if you change it to integer you dont need to add it;
And now all what you need to do is sort
Collection.sort(intervals);
I have my lovely little quick sort method ready to go, but I am unsure how to incorporate into a GUI (this will be my first GUI) and GUI do not like public statics and what-not...
So any ideas/know-how one to do a quick sort in a GUI without the publics etc would be amazing!
private void sortNumbersButtonActionPerformed(java.awt.event.ActionEvent evt) {
public static void main(String[] args) {
int a[]={23,44,1,2009,2,88,123,7,999,1040,88};
quickSort(a, 0, a.length - 1);
System.out.println(a);
ArrayList al = new ArrayList();
}
public static void quickSort(int[] a, int p, int r)
{
if(p<r)
{
int q=partition(a,p,r);
quickSort(a,p,q);
quickSort(a,q+1,r);
}
}
private static int partition(int[] a, int p, int r) {
int x = a[p];
int i = p-1 ;
int j = r+1 ;
while (true) {
i++;
while ( i< r && a[i] < x)
i++;
j--;
while (j>p && a[j] > x)
j--;
if (i < j)
swap(a, i, j);
else
return j;
}
}
private static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
One simple option is to present your items in a JList. Here's a tutorial.
Nothing prevents you from using a static method in a GUI application.
Good day! I have here a Java program that does the quicksort. It reads a file then sorts the first 10,000 words in it. I followed the pseudocode of Thomas Cormen in his Introduction to Algorithms, Second Ed.
import java.io.*;
import java.util.*;
public class SortingAnalysis {
public static int partition(String[] A, int p, int r) {
String x = A[r];
int i = p-1;
for (int j=p; j < r-1; j++) {
int comparison = A[j].compareTo(x);
if (comparison<=0) {
i=i+1;
A[i] = A[j];
}
}
A[i+1] = A[r];
return i+1;
}
public static void quickSort(String[] a, int p, int r) {
if (p < r) {
int q = partition(a, p, r);
quickSort(a, p, q-1);
quickSort(a, q+1, r);
}
}
public static void main(String[] args) {
final int NO_OF_WORDS = 10000;
try {
Scanner file = new Scanner(new File(args[0]));
String[] words = new String[NO_OF_WORDS];
int i = 0;
while(file.hasNext() && i < NO_OF_WORDS) {
words[i] = file.next();
i++;
}
long start = System.currentTimeMillis();
quickSort(words, 0, words.length-1);
long end = System.currentTimeMillis();
System.out.println("Sorted Words: ");
for(int j = 0; j < words.length; j++) {
System.out.println(words[j]);
}
System.out.print("Running time: " + (end - start) + "ms");
}
catch(SecurityException securityException) {
System.err.println("Error");
System.exit(1);
}
catch(FileNotFoundException fileNotFoundException) {
System.err.println("Error");
System.exit(1);
}
}
}
However, when I run the code, the console says
Exception in thread "main" java.lang.StackOverflowError
at SortingAnalysis.partition and quickSort
I thought that the error was just because of the large size (ie, 10000) so I decreased it to 100 instead. However, it still doesn't sort the first 100 words from a file, rather, it displays the 100th word 100 times.
Please help me fix the code. I'm new in Java and I need help from you guys. Thank you very much!
EDIT: I now edited my code. It doesn't have an error now even when the NO_OF_WORDS reaches 10000. The problem is it halts the wrong sequence.
You have two problems:
the loop in partition() should run to j <= r - 1, you are jumping out early.
You are not swapping elements. Try the following code:
public static int partition(String[] A, int p, int r) {
String x = A[r];
int i = p - 1;
for (int j = p; j <= r - 1; j++) {
int comparison = A[j].compareTo(x);
if (comparison <= 0) {
i = i + 1;
swap(A, i, j);
}
}
swap(A, i + 1, r);
return i + 1;
}
public static void swap(String[] a, int i, int j) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;
}
Looking at the Quicksort algo of wikipedia, the partition algo is the following :
// left is the index of the leftmost element of the array
// right is the index of the rightmost element of the array (inclusive)
// number of elements in subarray = right-left+1
function partition(array, 'left', 'right', 'pivotIndex')
'pivotValue' := array['pivotIndex']
swap array['pivotIndex'] and array['right'] // Move pivot to end
'storeIndex' := 'left'
for 'i' from 'left' to 'right' - 1 // left ≤ i < right
if array['i'] < 'pivotValue'
swap array['i'] and array['storeIndex']
'storeIndex' := 'storeIndex' + 1
swap array['storeIndex'] and array['right'] // Move pivot to its final place
return 'storeIndex'
In your method you don't use the pivotIndex value, you base your pivotValue on the right index. You need to add this parameter to your method.
Following the wiki algo it should be like this :
public static int partition(String[] A, int p, int r, int pivotIdx) {
String x = A[pivotIdx];
String tmp = A[pivotIdx];
A[pivotIdx] = A[r];
A[r]=tmp;
int i = p;
for (int j=p; j < r; j++) {
int comparison = A[j].compareTo(x);
if (comparison<=0) {
tmp=A[i];
A[i] = A[j];
A[j]=tmp;
i++;
}
}
tmp=A[i];
A[i] = A[r];
A[r]=tmp;
return i;
}