Sorting a String Array alphabetically by Selection Sort? - java

Im working on a program that alphabetically sorts a string array using compareTo method and selection sort.
Im having an issue within my minimumPosition method below. The method is designed to take the smallest element in a tail region of the array so that the selection sort program can conveniently sort the list.
My issue is that when I sort the list and print it via the tester it prints it out reverse alphabetically with a decrepency in-front. e.g. (c ,z,x,y...,b,a) opposed to (a,b,c.. y,x,z)
/**
SelectionSorter class sorts an array of Strings alphabetically.
It uses the selection sort algorithm.
*/
public class SelectionSorter
{
private String[] a;
/**
Constructs the selection sorter
#param anArray the array to sort
*/
public SelectionSorter4 (String[] anArray)
{
a = anArray;
}
/**
Sorts the array managed by this selection sorter
*/
public void sort ()
{
for (int i = 0 ; i < a.length - 1 ; i++)
{
int minPos = minimumPosition (i);
swap (minPos, i);
}
}
/**
Finds the smallest element in a tail region of the array.
The elements are String objects in this case, and the
comparison is based on the compareTo method of String.
#param from the first position of the tail region
#return the position of the smallest element in tail region
*/
private int minimumPosition (int from)
{
String holder = a [from];
int position = from;
for (int i = from ; i < a.length ; i++)
{
if (a [i].compareTo (holder) > 0)
{
holder = a [i];
position = i;
}
}
return position;
}
/**
Swaps two entries of the array
#param i the first position to swap
#param j the second position to swap
*/
private void swap (int i, int j)
{
String temp = a [i];
a [i] = a [j];
a [j] = temp;
}
}
Tester class: Relevant but there are no issues here.
/**
Tests the SelectionSorter4 class which sorts an array of Strings
alphabetically.
*/
import java.util.* ;
public class SelectionSorterTester
{
public static void main(String[] args)
{
String[] a = randomStringArray(40, 6) ;
SelectionSorter sorter = new SelectionSorter(a) ;
System.out.println(toString(a)) ;
sorter.sort() ;
System.out.println("----------Sorted:") ;
System.out.println(toString(a)) ;
System.out.println("--------------------------------") ;
}
/**
Returns a string representation of the array of Strings
#param array the array to make a string from
#return a string like [a1, a2, ..., a_n]
*/
public static String toString(String[] array)
{
String result = "[" ;
for (int i = 0 ; i < array.length - 1; i++) {
result += array[i] + ", " ;
}
result += array[array.length - 1] + "]" ;
return result ;
}
/**
Creates an array filled with random Strings.
#param length the length of the array
#param n the number of possible letters in a string
#return an array filled with length random values
*/
public static String[] randomStringArray(int length, int n)
{
final int LETTERS = 26 ;
String[] a = new String[length] ;
Random random = new Random(53) ;
for (int i = 0 ; i < length ; i++) {
String temp = "" ;
int wordLength = 1 + random.nextInt(n) ;
for (int j = 0 ; j < wordLength ; j++) {
char ch = (char)('a' + random.nextInt(LETTERS)) ;
temp += ch ;
}
a[i] = temp ;
}
return a ;
}
}
I think the issue lies within the minimumPosition method but it looks correct to me.

If you want ascendant order,
Change
if (a [i].compareTo (holder) > 0)
to
if (a [i].compareTo (holder) < 0)
Compares this object with the specified object for order. Returns a
negative integer, zero, or a positive integer as this object is less
than, equal to, or greater than the specified object.
Read more: Comparable#compareTo(..)

Related

Writing a toString method for 2D arrays

I have some code for a 2D array but I don't want spaces at the end of each row before I start a new row. For some reason, I can't find where I'm messing up because a space is being put at the end of each row. Basically what I'm trying to do is input a 2D array and the output should make it look the same as the input, except for the {}'s and it'll be a string. For example,
Input:
{1, 2, 3},
{4, 5, 6};
Output:
1 2 3
4 5 6
public class Matrix {
// the dimensions of the matrix
private int numRows;
private int numColumns;
// the internal storage for the matrix elements
private int data[][];
/**
* #param d - the raw 2D array containing the initial values for the Matrix.
*/
public Matrix(int d[][])
{
// d.length is the number of 1D arrays in the 2D array
numRows = d.length;
if(numRows == 0)
numColumns = 0;
else
numColumns = d[0].length; // d[0] is the first 1D array
// create a new matrix to hold the data
data = new int[numRows][numColumns];
// copy the data over
for(int i=0; i < numRows; i++)
for(int j=0; j < numColumns; j++)
data[i][j] = d[i][j];
}
/**
* Returns a String representation of this Matrix.
*/
#Override // instruct the compiler that we intend for this method to override the superclass' (Object) version
public String toString() {
// TODO: replace the below return statement with the correct code.
String arrString = "";
for(int i = 0; i < data.length; i++) {
for(int j = 0; j < data[i].length; j++) {
arrString += data[i][j] + " ";
}
arrString += "\n";
}
return arrString;
}
Next time please post a runnable example.
Your problem was that you always added a space after the item, no matter if it was the last one in the line. I now check that with a conditional + (j == data[i].length - 1 ? "" : " ");
Hint: It's not good to concatenate Strings. Use StringBuilder for better performance an memory usage. I added a second method toString2() to show how it's done.
package stackoverflow;
public class Matrix {
// the dimensions of the matrix
private final int numRows;
private int numColumns;
// the internal storage for the matrix elements
private final int data[][];
/**
* #param d - the raw 2D array containing the initial values for the Matrix.
*/
public Matrix(final int d[][]) {
// d.length is the number of 1D arrays in the 2D array
numRows = d.length;
if (numRows == 0)
numColumns = 0;
else
numColumns = d[0].length; // d[0] is the first 1D array
// create a new matrix to hold the data
data = new int[numRows][numColumns];
// copy the data over
for (int i = 0; i < numRows; i++)
for (int j = 0; j < numColumns; j++)
data[i][j] = d[i][j];
}
/**
* Returns a String representation of this Matrix.
*/
#Override // instruct the compiler that we intend for this method to override the superclass' (Object) version
public String toString() {
// TODO: replace the below return statement with the correct code.
String arrString = "";
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
arrString += data[i][j] + (j == data[i].length - 1 ? "" : " ");
}
arrString += "\n";
}
return arrString;
}
public String toString2() {
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.length; i++) {
for (int j = 0; j < data[i].length; j++) {
sb.append(data[i][j] + (j == data[i].length - 1 ? "" : " "));
}
sb.append("\n");
}
return sb.toString();
}
public static void main(final String[] args) {
final int[][] arr = new int[2][3];
arr[0][0] = 4;
arr[0][1] = 6;
arr[0][2] = 8;
arr[1][0] = 8;
arr[1][1] = 16;
arr[1][2] = 23;
final Matrix m = new Matrix(arr);
System.out.println("Matrix:\n" + m);
System.out.println("Matrix 2:\n" + m.toString2());
}
}
Output:
Matrix:
4 6 8
8 16 23
Matrix 2:
4 6 8
8 16 23
The Answer by JayC667 seems to correctly address your Question.
Stream, lambda, & method reference
For fun, here is an alternative approach using stream, lambda, and method reference.
Define the array.
int[][] input = { { 1 , 2 , 3 } , { 4 , 5 , 6 } }; // Declaration, initialization.
Make a stream where each element is a row, an array of int values, from your two-dimensional array.
For each of those rows, each being a int[], make a stream of its int primitive values (an IntStream), convert each primitive to an Integer object (boxing), call each Integer object’s toString method to generate a piece of text. Collect those pieces of text by joining them into a longer String with a SPACE character as a delimiter.
So we have transformed each row into a String. Collect all those strings together, with a LINE FEED character as the delimiter. Then, we are done, with a single String object as a result.
All that work, in a single line of code!
String result =
Arrays
.stream( input ) // A series of integer arrays, etc element being a int[].
.map( // Convert each integer array into something else, a `String` object.
( int[] row ) -> Arrays.stream( row ).boxed().map( Object :: toString ).collect( Collectors.joining( " " ) )
)
.collect( Collectors.joining( "\n" ) ); // Join each row of text with the next, using Linefeed as delimiter.
Results.
1 2 3
4 5 6
Here is one way to return a formatted 2D array based on the anticipated width of the values.
%nd - specifies a field width of n digits, right aligned.
%-nd - specifies a field width of n digits, left aligned (would have spaces at end of line).
fields will be filled in with spaces where necessary.
public class TwoDtoString {
int[][] mat = { { 11, 222, 3333 }, { 433, 53, 633 }, { 73, 8, 9333 } };
static String FORMAT = "%5d"; // 5 digit field, right aligned.
public static void main(String[] args) {
TwoDtoString tos = new TwoDtoString();
System.out.println(tos.toString());
}
public String toString() {
StringBuilder sb = new StringBuilder();
for (int[] row : mat) {
sb.append(FORMAT.formatted(row[0]));
for (int i = 1; i < row.length; i++) {
sb.append(FORMAT.formatted(row[i]));
}
sb.append("\n");
}
return sb.toString();
}
}
prints
11 222 3333
433 53 633
73 8 9333

Problem with implementing bi-directional selection sort

I am trying to implement bi-directional selection sort(double selection sort).
A double-selection sort finds both the smallest and largest elements during its scan, and swaps the smallest into the first position, and the largest into the last position. The algorithm then proceeds looking at all the elements between the first and last.
I am able to get the logic required to perform the task.But,i think i am doing something wrong with comparing variables or maybe implementing comparable properly.
public void sort(T[] input) {
for(int i=0; i<input.length -1; i++){
int min = i;
int max = i;
for(int j=i+1; j<input.length; j++){
if(input[min].compareTo((input[j])) > 0 )
{
min = j;
T swap = input[min];
input[min] = input[i];
input[i] = swap;
}
}
for(int k=i+1; k<input.length; k++){
if(input[max].compareTo((input[k])) < 0 )
{
max = k;
T swap = input[max];
input[max] = input[i];
input[i] = swap;
}
}
}
}
///// Test File
/** Returns true if the input array is ordered (every element ≤
* the following one.)
*
* #param data Array to check
* #return True if array is ordered
*/
boolean isOrdered(Integer[] data) {
for(int i = 0; i < data.length - 1; ++i)
if(data[i] > data[i+1])
return false;
return true;
}
/** Counts the number of times x occurs in the array in.
*
* #param in Array
* #param x Element to count
* #return Count of x's in the array
*/
int countElement(Integer[] in, Integer x) {
int c = 0;
for(int i : in)
if(i == x)
c++;
return c;
}
/** Returns true if both arrays contain the same elements,
* disregarding order (i.e., is one a permutation of the other).
* #param in Unsorted array
* #param out Potentially-sorted array to check
* #return True if out is a permutation of in
*/
boolean sameElements(Integer[] in, Integer[] out) {
for(Integer i : in)
if(countElement(in,i) != countElement(out,i))
return false;
return true;
}
/** Creates an array of the given size filled with random values.
*
* #param size Size of the resulting array
* #return Array of random values
*/
Integer[] randomArray(int size) {
Integer[] arr = new Integer[size];
for(int i = 0; i < size; ++i)
arr[i] = Math.round((float)Math.random() * Integer.MAX_VALUE);
return arr;
}
/** Tests the DoubleSelectionSort dss against the unsorted data.
*
* #param dss Sorter to use
* #param data Array to sort and check
*/
void testSort(DoubleSelectionSort dss, Integer[] data) {
Integer[] sorted = Arrays.copyOf(data, data.length);
dss.sort(sorted);
assertTrue("Result of sort is not sorted in order", isOrdered(sorted));
assertTrue("Result of sort has different elements from input", sameElements(data, sorted));
}
#Test
public void testSort() {
System.out.println("sort");
DoubleSelectionSort<Integer> dss = new DoubleSelectionSort<>();
// Test on arrays size 0 to 100
for(int i = 0; i <= 100; ++i)
testSort(dss, randomArray(i));
}
}
testSort Failed : Result of Sort is not sorted in order
It seems that you are using wrong conditions in Sorting Logic of Selection Sort.
I have given here example of Selection Sort function with generic type. Please have a look at this:
public static <E extends Comparable<E>> void selectionSort(E[] list)
{
for(int i=0; i<list.length -1; i++)
{
int iSmall = i;
for(int j=i+1; j<list.length; j++)
{
if(list[iSmall].compareTo((list[j])) > 0 )
{
iSmall = j;
}
}
E iSwap = list[iSmall];
list[iSmall] = list[i];
list[i] = iSwap;
}
}

Trying to reduce Radix Sort program execution time (Java)

I have created an implementation of radixsort using ArrayLists of integer arrays. The code is functional however as input size increases passed about 100,000 execution time is far too high. I need this code to be able to handle an input of 1,000,000 integers. What can I do to optimize execution time?
public class RadixSort {
public static void main(String[] args) {
// generate and store 1,000,000 random numbers
int[] nums = generateNums(1000000);
// sort the random numbers
int[] sortedNums = radixSort(nums);
// check that the array was correctly sorted and print result
boolean sorted = isSorted(sortedNums);
if (sorted) {
System.out.println("Integer list is sorted");
} else {
System.out.println("Integer list is NOT sorted");
}
}
/**
* This method generates numCount random numbers and stores them in an integer
* array. Note: For our program, numCount will always equal 1,000,000.
*
* #return nums the new integer array
*/
public static int[] generateNums(int numCount) {
// create integer array with length specified by the user
int[] nums = new int[numCount];
int max = Integer.MAX_VALUE;
for (int i = 0; i < nums.length; i++) {
nums[i] = (int) (Math.random() * max + 1);
}
// return new integer array
return nums;
}
/**
* This method implements a radix sort
*
* #param nums
* the integer array to sort
* #return nums the sorted integer array
*/
public static int[] radixSort(int[] nums) {
// find max number of digits in an element in the array
int maxDigits = findMaxDigits(nums);
// specified decimal place
int digit = 1;
// create 10 buckets
ArrayList<Integer>[] buckets = new ArrayList[10];
// iterate through the list for as many times as necessary (maxDigits)
for (int j = 0; j < maxDigits; j++) {
// initialize buckets as ArrayLists
for (int i = 0; i < buckets.length; i++) {
buckets[i] = new ArrayList<Integer>();
}
// isolate digit at specified decimal place and add the number to the
// appropriate bucket
for (int i = 0; i < nums.length; i++) {
int last = (nums[i] / digit) % 10;
buckets[last].add(nums[i]);
// convert buckets to an integer array
nums = convertToIntArray(buckets, nums);
}
// update digit to find next decimal place
digit *= 10;
}
// return sorted integer array
return nums;
}
/**
* This method converts from an ArrayList of integer arrays to an integer array
*
* #param buckets
* the ArrayList of integer arrays
* #param nums
* the integer array to return
* #return nums the new integer array
*/
public static int[] convertToIntArray(ArrayList<Integer>[] buckets, int[] nums) {
// loop through the ArrayList and put elements in order into an integer array
int i = 0;
for (ArrayList<Integer> array : buckets) {
if (array != null) {
for (Integer num : array) {
nums[i] = num;
i++;
}
}
}
// return new integer array
return nums;
}
/**
* Method to find the max number of digits in a number in an integer array
*
* #param nums
* the integer array to search through
* #return maxLength the max number of digits in a number in the integer array
*/
public static int findMaxDigits(int[] nums) {
// find maximum number
int max = 0;
for (int i = 0; i < nums.length; i++) {
if (nums[i] > max) {
max = nums[i];
}
}
// find and return the number of digits in the maximum number
int maxLength = String.valueOf(max).length();
return maxLength;
}
/**
* This method is used for testing correct functionality of the above radixSort
* method.
*
* #param nums
* the integer array to check for correct sorting
* #return false if the array is sorted incorrectly, else return true.
*/
public static boolean isSorted(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1]) {
return false;
}
}
return true;
}
}

Need assistance locating the errors within the following code

The code attached below is suppose to produce this output:
The array is: 4 3 6 9 3 9 5 4 1 9
This array DOES contain 5.
Sorted by Arrays.sort(): 1 3 3 4 4 5 6 9 9 9
Sorted by Sweep Sort: 1 3 3 4 4 5 6 9 9 9
Sorted by Selection Sort: 1 3 3 4 4 5 6 9 9 9
Sorted by Insertion Sort: 1 3 3 4 4 5 6 9 9 9
But it doesn't. I followed the instruction in the book that I am reading and it didn't help. Can I get your opinion on what those errors might be? I'm not asking for solutions, I want to be pointed in the right direction as to where the errors are and what type of errors they are.
import java.util.Arrays;
/**
* This class looks like it's meant to provide a few public static methods
* for searching and sorting arrays. It also has a main method that tests
* the searching and sorting methods.
*
* TODO: The search and sort methods in this class contain bugs that can
* cause incorrect output or infinite loops. Use the Eclipse debugger to
* find the bugs and fix them
*/
public class BuggySearchAndSort {
public static void main(String[] args) {
int[] A = new int[10]; // Create an array and fill it with small random ints.
for (int i = 0; i < 10; i++)
A[i] = 1 + (int)(10 * Math.random());
int[] B = A.clone(); // Make copies of the array.
int[] C = A.clone();
int[] D = A.clone();
System.out.print("The array is:");
printArray(A);
if (contains(A,5))
System.out.println("This array DOES contain 5.");
else
System.out.println("This array DOES NOT contain 5.");
Arrays.sort(A); // Sort using Java's built-in sort method!
System.out.print("Sorted by Arrays.sort(): ");
printArray(A); // (Prints a correctly sorted array.)
bubbleSort(B);
System.out.print("Sorted by Bubble Sort: ");
printArray(B);
selectionSort(C);
System.out.print("Sorted by Selection Sort: ");
printArray(C);
insertionSort(D);
System.out.print("Sorted by Insertion Sort: ");
printArray(D);
}
/**
* Tests whether an array of ints contains a given value.
* #param array a non-null array that is to be searched
* #param val the value for which the method will search
* #return true if val is one of the items in the array, false if not
*/
public static boolean contains(int[] array, int val) {
for (int i = 0; i < array.length; i++) {
if (array[i] == val)
return true;
else
return false;
}
return false;
}
/**
* Sorts an array into non-decreasing order. This inefficient sorting
* method simply sweeps through the array, exchanging neighboring elements
* that are out of order. The number of times that it does this is equal
* to the length of the array.
*/
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; i++) {
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
/**
* Sorts an array into non-decreasing order. This method uses a selection
* sort algorithm, in which the largest item is found and placed at the end of
* the list, then the second-largest in the next to last place, and so on.
*/
public static void selectionSort(int[] array) {
for (int top = array.length - 1; top > 0; top--) {
int positionOfMax = 0;
for (int i = 1; i <= top; i++) {
if (array[1] > array[positionOfMax])
positionOfMax = i;
}
int temp = array[top]; // swap top item with biggest item
array[top] = array[positionOfMax];
array[positionOfMax] = temp;
}
}
/**
* Sorts an array into non-decreasing order. This method uses a standard
* insertion sort algorithm, in which each element in turn is moved downwards
* past any elements that are greater than it.
*/
public static void insertionSort(int[] array) {
for (int top = 1; top < array.length; top++) {
int temp = array[top]; // copy item that into temp variable
int pos = top - 1;
while (pos > 0 && array[pos] > temp) {
// move items that are bigger than temp up one position
array[pos+1] = array[pos];
pos--;
}
array[pos] = temp; // place temp into last vacated position
}
}
/**
* Outputs the ints in an array on one line, separated by spaces,
* with a line feed at the end.
*/
private static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(" ");
System.out.print(array[i]);
}
System.out.println();
}
}
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; i++) { //<---- wrong increment. it should be j++
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
in this part is at least one error. You should check your loops if your programm does not determine.
I have finished my project and decided to drop a help
public static void main(String[] args) {
int[] A = new int[10]; // Create an array and fill it with small random ints.
for (int i = 0; i < 10; i++)
A[i] = 1 + (int)(10 * Math.random());
int[] B = A.clone(); // Make copies of the array.
int[] C = A.clone();
int[] D = A.clone();
System.out.print("The array is:");
printArray(A);
if (contains(A,5))
System.out.println("This array DOES contain 5.");
else
System.out.println("This array DOES NOT contain 5.");
Arrays.sort(A); // Sort using Java's built-in sort method!
System.out.print("Sorted by Arrays.sort(): ");
printArray(A); // (Prints a correctly sorted array.)
sweepSort(B);
System.out.print("Sorted by Sweep Sort: "); //Changed name
printArray(B);
selectionSort(C);
System.out.print("Sorted by Selection Sort: ");
printArray(C);
insertionSort(D);
System.out.print("Sorted by Insertion Sort: ");
printArray(D);
}
public static boolean contains(int[] array, int val) {
for (int i = 0; i < array.length; i++) {
if (array[i] == val)
return true;
//removed else
} //removed return false;
return false;
}
public static void sweepSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; j++) { //'i++' => 'j++'
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
public static void selectionSort(int[] array) {
for (int top = array.length - 1; top > 0; top--) {
int positionOfMax = 0;
for (int i = 1; i <= top; i++) {
if (array[i] > array[positionOfMax]) //replaced [1]
positionOfMax = i;
}
int temp = array[top]; // swap top item with biggest item
array[top] = array[positionOfMax];
array[positionOfMax] = temp;
}
}
public static void insertionSort(int[] array) {
for (int top = 1; top < array.length; top++) {
int temp = array[top]; // copy item that into temp variable
int pos = top - 1;
while (pos >= 0 && array[pos] >= temp) { // '>' => '>='
// move items that are bigger than temp up one position
array[pos+1] = array[pos];
pos--;
}
array[pos+1] = temp; // place temp into last vacated position //added '+1'
}
}
private static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(" ");
System.out.print(array[i]);
}
System.out.println();
}
}
Thank for all your help guys. Using the debugger I found the for main issues
Error 1:
public static void sweepSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; i++) {<------// need change i++ to j++
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
Error 2 and 3:
public static void insertionSort(int[] array) {
for (int top = 1; top < array.length; top++) {
int temp = array[top]; // copy item that into temp variable
int pos = top - 1;
while (pos > 0 && array[pos] > temp) { //<----- need to change '>' to '>='
// move items that are bigger than temp up one position
array[pos+1] = array[pos];
pos--;
}
array[pos ] = temp; // place temp into last vacated position // <------------------------need to change 'array[pos ]' to 'array[pos + 1]'
}
}
Error 4:
public static boolean contains(int[] array, int val) {
for (int i = 0; i < array.length; i++) {
if (array[i] == val)
return true;
else //<---------- need to remove this
return false; //<---------- need to remove this
}
return false;
}
package sort;
import java.util.Arrays;
/**
* This class looks like it's meant to provide a few public static methods
* for searching and sorting arrays. It also has a main method that tests
* the searching and sorting methods.
*
* TODO: The search and sort methods in this class contain bugs that can
* cause incorrect output or infinite loops. Use the Eclipse debugger to
* find the bugs and fix them
*/
public class BuggySearchAndSort {
public static void main(String[] args) {
int[] A = new int[10]; // Create an array and fill it with small random ints.
for (int i = 0; i < 10; i++)
A[i] = 1 + (int)(10 * Math.random());
int[] B = A.clone(); // Make copies of the array.
int[] C = A.clone();
int[] D = A.clone();
System.out.print("The array is:");
printArray(A);
if (contains(A,5))
System.out.println("This array DOES contain 5.");
else
System.out.println("This array DOES NOT contain 5.");
Arrays.sort(A); // Sort using Java's built-in sort method!
System.out.print("Sorted by Arrays.sort(): ");
printArray(A); // (Prints a correctly sorted array.)
bubbleSort(B);
System.out.print("Sorted by Bubble Sort: ");
printArray(B);
selectionSort(C);
System.out.print("Sorted by Selection Sort: ");
printArray(C);
insertionSort(D);
System.out.print("Sorted by Insertion Sort: ");
printArray(D);
}
/**
* Tests whether an array of ints contains a given value.
* #param array a non-null array that is to be searched
* #param val the value for which the method will search
* #return true if val is one of the items in the array, false if not
*/
public static boolean contains(int[] array, int val) {
for (int i = 0; i < array.length; i++) {
if (array[i] == val)
return true;
}
return false;
}
/**
* Sorts an array into non-decreasing order. This inefficient sorting
* method simply sweeps through the array, exchanging neighboring elements
* that are out of order. The number of times that it does this is equal
* to the length of the array.
*/
public static void bubbleSort(int[] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length-1; j++) {
if (array[j] > array[j+1]) { // swap elements j and j+1
int temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
}
/**
* Sorts an array into non-decreasing order. This method uses a selection
* sort algorithm, in which the largest item is found and placed at the end of
* the list, then the second-largest in the next to last place, and so on.
*/
public static void selectionSort(int[] array) {
for (int top = array.length - 1; top > 0; top--) {
int positionOfMax = 0;
for (int i = 0; i <= top; i++) {
if (array[i] > array[positionOfMax])
positionOfMax = i;
}
int temp = array[top]; // swap top item with biggest item
array[top] = array[positionOfMax];
array[positionOfMax] = temp;
}
}
/**
* Sorts an array into non-decreasing order. This method uses a standard
* insertion sort algorithm, in which each element in turn is moved downwards
* past any elements that are greater than it.
*/
public static void insertionSort(int[] array) {
for (int top = 1; top < array.length; top++) {
int temp = array[top]; // copy item that into temp variable
int pos = top ;
while (pos > 0 && array[pos-1] >= temp) {
// move items that are bigger than temp up one position
array[pos] = array[pos-1];
pos--;
}
array[pos] = temp; // place temp into last vacated position
}
}
/**
* Outputs the ints in an array on one line, separated by spaces,
* with a line feed at the end.
*/
private static void printArray(int[] array) {
for (int i = 0; i < array.length; i++) {
System.out.print(" ");
System.out.print(array[i]);
}
System.out.println();
}
}

"ArrayIndexOutOfBoundsException" error when trying to add two int arrays

I'm trying to make an implementation of 'adding' the elements of two arrays in Java.
I have two arrays which contain integers and i wanna add them. I dont want to use immutable variables. I prefer do sth like that : a.plus(b);
The problem is when i add 2 arrays with different length.It tries to add the elements of b to a, but if b has a bigger length it flags an error "ArrayIndexOutOfBoundsException".
I can understand why that's happening. But how can i solve this?
How can i expand array a? :/
public void plus(int[] b)
{
int maxlength = Math.max( this.length, b.length );
if (maxlength==a.length)
{
for (int i = 0; i <= maxlength; i++)
{
a[i] = a[i] + b[i]; //ArrayIndexOutOfBoundsException error
}
}
}
i <= maxlength replace this with i < maxlength.
Your array index is starting at zero, not at one.
So the length of the array is one less than the end index of the array.
When you use <= you are trying to go one element after the last element in your array, Hence the exception.
Also you got to check the length of array b. If length of array b is smaller than a, you will end up facing the same exception.
int maxlength = Math.min( this.length, b.length ); is more appropriate.
Or incase if you don't want to miss out any elements in either of the arrays while adding, ArrayList is the answer for you. ArrayList is the self expanding array you are looking for.
Here is how you can do that -
// First ArrayList
ArrayList<Integer> a = new ArrayList<Integer>();
a.add(1);
a.add(2);
a.add(3);
// Second ArrayList
ArrayList<Integer> b = new ArrayList<Integer>();
b.add(1);
b.add(2);
b.add(3);
b.add(4);
int maxlength = Math.max(a.size(), b.size());
// Add the elements and put them in the first ArrayList in the corresponding
// position
for (int i = 0; i < maxlength; i++) {
if (i < a.size()) {
if (i < b.size()) {
int j = a.get(i);
a.set(i, j + b.get(i));
}
} else {
a.add(i, b.get(i));
}
}
for (int j : a) {
System.out.println(j);
}
How can i expand array a?
Don't use arrays if you need variable-size data structures. Use Lists.
How about this:
private int[] a;
/**
* Adds the specified array to our array, element by element, i.e.
* for index i, a[i] = a[i] + b[i]. If the incoming array is
* longer, we pad our array with 0's to match the length of b[].
* If our array is longer, then only the first [b.length] values
* of our array have b[] values added to them (which is the same
* as if b[] were padded with 0's to match the length of a[].
*
* #param b the array to add, may not be null
*/
public void plus(final int[] b)
{
assert b != null;
if (a.length < b.length) {
// Expand a to match b
// Have to move a to a larger array, no way to increase its
// length "dynamically", i.e. in place.
final int[] newA = new int[b.length];
System.arraycopy(a, 0, newA, 0, a.length);
// remaining new elements of newA default to 0
a = newA;
}
for (int i = 0; i < b.length; i++)
{
a[i] = a[i] + b[i];
}
}
Another version:
private ArrayList<Integer> aList;
public void plusList(final int[] b)
{
assert b != null;
if (aList.size() < b.length) {
aList.ensureCapacity(b.length);
}
for (int i = 0; i < b.length; i++)
{
if (i < aList.size()) {
aList.set(i, aList.get(i) + b[i]);
} else {
aList.add(b[i]);
}
}
}
Edit: Here's the full class with sample run from data in comments
public class AddableArray {
private int[] a;
public AddableArray(final int... a) {
this.a = a;
}
/**
* Adds the specified array to our array, element by element, i.e.
* for index i, a[i] = a[i] + b[i]. If the incoming array is
* longer, we pad our array with 0's to match the length of b[].
* If our array is longer, then only the first [b.length] values
* of our array have b[] values added to them (which is the same
* as if b[] were padded with 0's to match the length of a[].
*
* #param b the array to add, may not be null
*/
public void plus(final int[] b)
{
assert b != null;
if (a.length < b.length) {
// Expand a to match b
// Have to move a to a larger array, no way to increase its
// length "dynamically", i.e. in place.
final int[] newA = new int[b.length];
System.arraycopy(a, 0, newA, 0, a.length);
// remaining new elements of newA default to 0
a = newA;
}
for (int i = 0; i < b.length; i++)
{
a[i] = a[i] + b[i];
}
}
int[] get() {
return a;
}
#Override
public String toString() {
final StringBuilder sb = new StringBuilder("a[] = [ ");
for (int i = 0; i < a.length; i++) {
if (i > 0) sb.append(", ");
sb.append(a[i]);
}
sb.append(" ]");
return sb.toString();
}
public static void main (final String[] args) {
final AddableArray myAddableArray = new AddableArray(1,2,3);
System.out.println("Elements before plus(): ");
System.out.println(myAddableArray.toString());
final int b[]={1,2,3,4};
myAddableArray.plus(b);
System.out.println("Elements after plus(): ");
System.out.println(myAddableArray.toString());
}
}
Sample run:
Elements before plus():
a[] = [ 1, 2, 3 ]
Elements after plus():
a[] = [ 2, 4, 6, 4 ]
maxlength is the max between the size of a[] and b[], so in a loop from 0 to maxlength, you will get an ArrayIndexOutOfBoundsException when i exceeds the min of the size of a[] and b[].
Try this:
public void plus(int[] b)
{
Polynomial a = this;
int[] c;
int maxlength;
if (a.length>b.length) {
c=a;
maxlength=a.length;
} else {
c=b;
maxlength=b.length;
}
int ca, cb;
for (int i = 0; i < maxlength; i++)
{
if (i<this.length)
ca=a[i];
else
ca=0;
if (i<b.length)
cb=b[i];
else
cb=0;
c[i] = ca + cb;
}
}
Try replacing:
for (int i = 0; i <= maxlength; i++)
with:
for (int i = 0; i < maxlength; i++)

Categories