I am trying the following code for heap sort which is giving ArrayIndexOutOfBoundsException exception:
package com.Sorting;
import java.util.Arrays;
public class HeapSort {
private static int arr[];
private static int l,r,max,hsize;
/**
* #param args
*/
public static void main(String[] args) {
int []numbers={55,2,93,1,23,10,66,12,7,54,3};
System.out.println(Arrays.toString(numbers));
HeapSort(numbers);
System.out.println(Arrays.toString(numbers));
}
private static void HeapSort(int myarr[]) {
// TODO Auto-generated method stub
arr = myarr;
hsize = arr.length - 1;
BuildHeap(arr);
for(int i = hsize;i>0;i--)
{
swap(0,i);
hsize--;
SatisfyHeap(arr,0);
}
}
private static void BuildHeap(int[] arr) {
// TODO Auto-generated method stub
for(int i = hsize/2; i>=0;i--)
{
SatisfyHeap(arr, i);
}
}
private static void SatisfyHeap(int[] arr, int i) {
// TODO Auto-generated method stub
l = 2*i;
r = 2*i+1;
if(l<=hsize && arr[l]>arr[i])
// if(arr[l]>arr[i] && l<=hsize )
{
max = l;
}
else
max = i;
if(r<=hsize && arr[r]>arr[max])
{
max = r;
}
if(max!=i)
{
swap(i,max);
SatisfyHeap(arr, max);
}
}
private static void swap(int i, int max) {
// TODO Auto-generated method stub
int temp = arr[i];
arr[i] = arr[max];
arr[max] = temp;
}
}
The above code does not give any error if I just swap the expressions used on the left hand side and right hand side in the if statement of SatisfyHeap method. i.e. you can try commenting the third line of the SatisfyHeap method and uncomment the fourth line. Please help to understand this magic.
Short answer
The magic is called "short-circuit evaluation" and it was designed speciifcally for the cases like this.
Longer answer
In Java and many other languages logicallly code
if (condition1 && condition2) {
do something
}
is equivalent to
if (condition1) {
if (condition2) {
do something
}
}
By "equivalent" here I mean that if condition2 is something to be computed it will not be computed if condition1 happens to be false. Also this is correct from the boolean logic point of view. This trick is useful in two respects. First, it improves performance by skipping evaluation calculation2. Secondly, it is useful in cases such as yours were condition1 is a "guard condition" for condition2.
Another example is function isEmptyString that is implemented by many Java-developers in a following way
public static boolean isEmptyString(String s) {
return (string == null) || (string.length() == 0);
}
Without short-circuting logic, this expression would raise a NullPointerException if s happens to be null.
Your specific case (Why ArrayIndexOutOfBoundsException at all?)
Another point of your question might be "How it happens that there is ArrayIndexOutOfBoundsException at all?". To answer this question consider the case when the very first element is actually the largest in the heap and we should move it down to the last layer of the tree. This movement down is implemented by your SatisfyHeap. So now assume that we did last swap that moved the biggest element to the bottom. Now as max was changed we'll do one more recursive call and in that call i > arr.length / 2 so l = 2*i > arr.length and thus the exception happens.
Side-note, I'd say that unless you pre-allocate arr to be bigger than actual heap size storing hsize independently from arr.length is a bad idea that makes code harder to understand.
Following gives you an error
if(arr[l]>arr[i] && l<=hsize )
because l is greater than the size of the array and you are trying to get the array element by passing l which is out of array's bounds.
Following works for you
if(l<=hsize && arr[l]>arr[i])
because in the if condition, the first thing that is evaluated is the expression l<=hsize. Since l is greater than hsize, the expression evaluates to false. Since the two clauses of your if predicate are joined with an && operator, as per the short circuiting rules, the expression in the second clause is not even evaluated saving you from accessing the array with an out of bound index. Therefore you don't get any error.
Related
I'm looking for an elegant way to express this pseudo code. For my assignment, I cannot change the method signature or parameter type.
private static int smallest(int... nums)
{
return Arrays.stream(nums).min().getAsInt();
}
All I'm trying to do is take a huge varying list of ints as a parameter from the method call and return the smallest int of all the int parameters. I've tried to google and read the API to find out how to correctly implement this, but I've gotten only this far. Can someone help me syntactically correct this to compile and output correctly?
I cannot correctly post my console errors with formatting, so I'm posting it as an update to my OP. To answer #Marvin I'm getting this error in my compiler...
Methods1.java:25: error: cannot find symbol
int small = Arrays.stream(nums).min().getAsInt();
^
symbol: variable Arrays
location: class Methods1
1 error
You almost had it, it's getAsInt() instead of get():
private static int smallest(int... nums) {
return Arrays.stream(nums).min().getAsInt();
}
Complete working sample on ideone.com:
import java.util.Arrays;
class Ideone {
public static void main (String[] args) {
int[] nums = new int[] { 7, -2, 5, 12 };
System.out.println(smallest(nums));
}
private static int smallest(int... nums) {
return Arrays.stream(nums).min().getAsInt();
}
}
Prints:
-2
You could iterate over the whole array like this
private static int smallest(int[] array)
{
//check if the array is empty
if(array.length == 0)
{
//handle, whatever happens if the array is empty
return -1; //maybe you should throw an exception here
}
//storing the smallest found value, start with the first int in the array
int smallest = array[0];
//the iteration
for(int i : array)
{
//check if the current checked value is smaller than the smallest found...
if(i < smallest)
{
//...and if it is, set it as the smallest found value
smallest = i;
}
}
//finally, return the smallest value
return smallest;
}
This should solve your current problem, but in most cases i'd rather recommend to use a pre sorted array or list instead. If the data in it is already stored in ascending order, the first element would always be the lowest and the last element always the highest value.
This method takes an infinite unknown variable quantity of parameters by using varargs as it's argument. Combining all the parameters added from it's call from main into an array of the same type. This was designed to account for mutability of the original method call in main. Finally, returning the smallest integer of all the parameters.
I'm a fairly new programmer, second year into computer science, and I'm not sure if this is even useful for anyone, but I hope it helps. Thanks to everyone here for your awesome tips and error catches. My issue was I forgot to import my Array class and one of my method calls from stream class was incorrectly named.
Lastly, for any veteran programmers out there, aside from this looking snappy and elegant, does this statement execute any faster than doing a simple foreach loop and comparing the num to the last smallest one?
import java.util.Arrays;
public class Test
{
public static void main(String[] args)
{
// Enter as many as you want here, can be more or less than three
int num1 = 23;
int num2 = 89;
int num3 = 9;
// Apply each variable as an argument for the method call
int smallestNumber = smallest(num1, num2, num3);
// Print out variable value to prove it works
System.out.print(smallestNumber);
}
private static Integer smallest(int... nums)
{
// Found an elegant way to do the stubbed out block of code
// I left the code down there to show what is going on here
try
{
return Arrays.stream(nums).min().getAsInt();
}
catch (Exception e)
{
return null;
}
// The above code is essentially doing the below code
/*try
{
// Initialize Variable to start of array
int smallest = nums[0];
// For:Each Loop: go through each parameter and assign it a local variable to compare with
for(int i : nums)
{
// compare if smaller
if(i < smallest)
{
// If true, set as smallest
smallest = i;
}
}
return smallest;
}
catch (Exception e)
{
return null;
}*/
}
}
Hi all I am very new for the Java. I would like to sort below array of strings as per LastName then on FirstName without use of any API i.e. I am not supposed to use Arrays.sort() , compareTo(), equals() etc..
Input array String
String [][]name={{"Jen","Eric"},
{"Brain","Adams"},
{"Jon","Methew"},
{"Antino","Ronald"},
{"Cris","Ronald"}
};
my out put should be like.
Brain,Adams
Jen,Eric
Jon,Methew
Antino,Ronald
Cris,Ronald
Please Help.
public class StringArraySort {
public static void main(String[] args) {
//System.out.println(str.length);
String [][]name={{"Jen","Eric"},
{"Brain","Adams"},
{"Jon","Methew"},
{"Antino","Ronald"},
{"Cris","Ronald"}
};
String []str1= new String [name.length];
String []str2= new String [name.length];
for(int i=1;i<name.length;i++)
{
int j=i;
str1[i]=name[i][j];
str2[i]=name[i-1][j];
//System.out.println(str1[i]+" "+str2[i]);
}
/*for(String tmp:name)
{
char a[] = new char[tmp.length()] ;
//System.out.println(tmp);
for(int i=0;i<tmp.length();i++)
{
a[i]=tmp.charAt(i);
System.out.println(a[i]);
}
}*/
}
}
I will not give you any code, as this is clearly an assignment, but here's some general guidance:
Don't try to put everything into main. You may not be allowed to use any exiting API, but you can define your own! Write your own compare and sort methods.
Start with a method compare(String, String) -> int, or isSmaller(String, String) -> boolean. Use String.toCharArray to get the individual characters and compare them, in pairs from both strings. Make sure to handle the case of the strings having different lengths.
Now write a method compare(String[], String[]) -> int. This can look very similar to the above (in fact, you could make a generic one for both), but it might be simpler to make this one specific for the "lastname-firstname" case, particularly since here you want to sort by the second element first.
Finally, write your own sort method. An in-place bubble sort should be the easiest and the algorithm can easily be found on the internet. Other sort algorithms are faster, but if speed is an issue, the requirement not to use any API is nonsensical in the first place. If you want to score bonus-points, though, you can try to implement an in-place quick sort, but only after you've got it running with the bubble sort.
Also, you should test each of those methods individually. Don't try to run your sort method before you've made sure your compare methods actually work. Call them individually with different outputs and see whether they yield the correct result.
public class NameSort {
public static void main(String[] args) {
String [][] names={{"Jen","Eric"},
{"Brain","Adams"},
{"Jon","Methew"},
{"Antino","Ronald"},
{"Cris","Ronald"}
};
for(int m=0;m<names.length;m++)
{
for(int n=m+1;n<names.length;n++)
{
if(myCompare(names[m][1],names[n][1])==1)
{
swap(names, names[m], names[n], m, n);
}
else if (myCompare(names[m][1],names[n][1])==0)
{
if(myCompare(names[m][0],names[n][0])==1)
{
swap(names, names[m], names[n], m, n);
}
}
}
}
for (int i=0;i<names.length;i++)
{
System.out.println(names[i][0]+" " +names[i][1] );
}
}
public static void swap(String [][] names,String[] a,String[] b,int m,int n)
{
names[n]=a;
names[m]=b;
}
public static int myCompare(String a, String b)
{
int minLength= a.length()<b.length()?a.length():b.length();
for(int i=0;i<minLength;i++)
{
if(a.charAt(i)>b.charAt(i))
{
return 1;
}
else if(a.charAt(i)<b.charAt(i)){
return -1;
}
}
if(a.length()>minLength)
return 1;
else if (b.length()> minLength )
return -1;
else
return 0;
}
}
In order to let you learn at least something, I am going to give you the answer in psuedo-code and let you do the coding. The solution is based on bubble sort and comparing names (=Strings) by looping on their characters
in bubble sort we iterate over the array, in each iteration, we compare two adjacent cells and possibly swap them so that they are in the correct order.
at the end of the 1st iteration, the biggest cell will be in the correct position (=last). so we start another iteration but skip the last cell. by the end of the 2nd iteration, the 2nd biggest cell will in its correct position. we cotinue iterating, each time going over one less cell until there are no more cells to iterate over.
I give you the comparing method:
The solution assumes you are allowed to call length() and charAt() methods of String class.
/**
* returns negative, zero or positive value
* if s1 is smaller, equal or bigger than s2, respectively
* comparison is lexicographical
*/
static int compareStrings(String s1, String s2)
{
int i = 0;
for (i = 0; i < s1.length() && i < s2.length(); i++) {
int diff = s1.charAt(i) - s2.charAt(i);
if (diff != 0) return diff;
}
if (i == s1.length()) {
if (i == s2.length()) return 0; // equal lengths
else return 1; // exhausted s2 before s1
}
return -1; // exhausted s1 before s2
}
seeing the loop in your code, I think one last note is in order: you should be aware that arrays in Java start with index 0 and the last cell is at length-1.
I'll preface my question with the statement that I am very new to Java, so I apologise if my code is totally disgusting to read.
What I'm trying to do: I'm writing a program that takes two integers from the user, a low value and a high value, and sends both integers to two different methods. Method #1 has a simple for loop and should print out all of the numbers between the lowest number and the highest number that are multiples of 3 or 5, and Method #2 does the same except for numbers that are multiples of 3 or 5 it also checks if that number is also a multiple of 6 and, if so, it prints the number and an asterisk next to it.
What I'm having trouble with: I'm pretty stumped on what I need to return from my methods & how to return anything at all. This is the first time I've worked on a method properly (just moved up from "Hello World) and from what I can see I don't really need to return anything at all. All the code that I've put in my methods pretty much complete the program, so I thought maybe returning the integers I sent would be enough, apparently it's not. So, without further ado, here's my code.
The Error:
javac BonusQ.java
.\MethodOne.java:19: error: illegal start of type
return(int lowestRange, int highestRange);
^
.\MethodTwo.java:36: error: illegal start of type
return(int lowestRange, int highestRange);
^
The Main:
import java.util.Scanner;
public class BonusQ
{
public static void main(String [] args)
{
Scanner scan = new Scanner(System.in);
int lowestRange = 0;
int highestRange = 0;
System.out.println("Enter the lowest integer in your range");
lowestRange = scan.nextInt();
System.out.println("Enter the highest integer in your range");
highestRange = scan.nextInt();
MethodOne.NoAsterisk(lowestRange, highestRange);
MethodTwo.Asterisk(lowestRange, highestRange);
}
}
MethodOne:
public class MethodOne
{
public static int NoAsterisk(int lowestRange, int highestRange)
{
for(int i = lowestRange; i <= highestRange; i++)
{
if (i%5 == 0)
{
System.out.println(i);
}
else if (i%3 == 0)
{
System.out.println(i);
}
}
}
return(int lowestRange, int highestRange);
}
MethodTwo:
public class MethodTwo
{
public static int Asterisk(int lowestRange, int highestRange)
{
for(int i = lowestRange; i <= highestRange; i++)
{
if (i%5 == 0)
{
if (i%5 == 0 && i%6 == 0)
{
System.out.println(i + "*");
}
else
{
System.out.println(i);
}
}
else if (i%3 == 0)
{
if (i%3 == 0 && i%6 == 0)
{
System.out.println(i + "*");
}
else
{
System.out.println(i);
}
}
}
}
return(int lowestRange, int highestRange);
}
Sorry if the post is a bit beefy to read, I just find that adding my thoughts on the code might help you explain to me what's going wrong, seeing as you may not know the extent of my incompetence :)
Thanks in advance.
Ok, Classes have members.
Members are either some variables or arrays of variables
and the methods of a class.
So you got
public class MyMethod
{
public static int Asterisk(int loRange, int hiRange)
{
// Do magic let's make a sum for this example
// You enter loRange and hiRange (you defined it above)
return loRange + hiRange // Here the method returns a result
}
}
// So then....
public static void main(String [] args)
{
// WHATEVER IS IN HERE RUNS ALWAYS FIRST.
z = Asterisk(1,2); // 1 and 2 is lo and hi range values ;)
// Z has a value of 3 now because Asterisk(1,2) returns 1 + 2
}
See how this works?
Now this works because you use the static definition (meaning there must not be an instance of MyMethod created first to use the method. It's not wrong, but if you can make a program do things with class instances, you better do it that way.
You make an instance of a class, this is called an object, using a special method. This method has the exact name of the Class and constructs an instance of it.
You should study now about constructors, abstract classes etc etc.
I can't say you do it wrong or right either. It is about what the program is all about and you should study the scope for variables and methods, and the encapsulation concept of Object Oriented Programming.
Using only static methods, goes against encapsulation principle, it is possibly wrong but I can't tell for sure.
I hope this helped you and gave you a good direction to go on with your study.
PS:
To return multiple results, you should return an array of variables, not just a variable.
You can also return nothing and just have it do the job to a needed array. This FORCES you though to make this array public. (Not a good practice)
Finally if multiple value returns are needed to just print them on the console... well, just do it in the method, no need to return anything really.
You don't need to return anything, being that the methods are printing out all the values.
You can change them into void methods, for example:
public static void asterisk(int lowest, int highest) {
//loops and if statements
//no return statement!
}
The code in the methods will run and voila, you are done!
EDIT: That being said, there's a lot more than can be done to make this code more Java-like, but for now this will work.
mmmmm...you can return types, and (int lowestRange, int highestRange) its not a type. Look at the method definition
public static int Asterisk(int lowestRange, int highestRange)
the return type is declared as int, so you should return an int value. You can do something like
return lowestRange;
return 1;
with that in consideration, the error should dissapear. The question is, why do you need to return a value? From what i've read, your methods are supose to print stuff, not to return stuff...
The return statements are out of the method. You have to put them before the close method brackets.
public class MyClass{
public int sum (int a, int b){
return a + b;
} // The return have to be before this brackets
}
So I've been fiddling with this problem for the past hour. I keep getting unexpected type error. It appears to be from a confliction between charAt and s.length. Any ideas on what could fix that?
class lab7
{
public static void main(String[] args)
{
String s = ("BCA");
}
public static String recursion(String s)
{
if (s.length()>=0)
{
if(s.charAt(s.length()) = A)
{
count++;
}
s.substring(0, s.length()-1);
}
return count;
}
}
There are several issues with this code, including some significant logic errors. However, the specific error you're getting is probably here:
if(s.charAt(s.length()) = A)
First, note that you're using = instead of ==, which does an assignment rather than a comparison. Also note that A should be in single quotes to be a character literal. Right now, Java thinks A is the name of a variable, which isn't defined. Finally, note that strings are zero-indexed, so looking up the character at position s.length() will give you a bounds error.
I hope this helps you get started! As a hint, although your function is named "recursion," does it actually use recursion?
Following code uses String class. For performance critical applications you might want to use StringBuffer / StringBuilder class accordingly.
class StringCounter
{
public static void main (String[] args)
{
int count = returnCount("ABCDABCDABCD", 0);
System.out.println(count);
}
public static int returnCount(String s, int count)
{
// You may want to do some validations here.
if(s.length()==0)
{
return count;
}
if(s.charAt(0)=='A')
{
return returnCount(s.substring(1), count+1);
}
else
{
return returnCount(s.substring(1), count);
}
}
}
The code simply slices the String parameter one character at a time and checks for the required character. Further on every invoke it will update the count and String parameter.
Any ideas on what could fix that?
Your function is not recursive. Recursive functions call themselves with manipulated/updated parameters.
As a thumb rule in recursive functions, always think in terms of manipulating function parameters.
Always have a base case that will terminate recursive calls.
Consider this snippet:
static int countA(String str) {
if (str == null || str.length() == 0) { /* nothing or "" contains 0 A's */
return 0;
}
return (str.charAt(0) == 'A' ? 1 : 0 ) /* 0 or 1 A's in first character */
+ countA(str.substring(1)); /* plus no. of A's in the rest */
}
And you call the function like this:
int a = countA("ABAABA"); /* a is 4 */
I realize now that this question was school related, but at least this snippet works as an exercise in understanding recursion.
I'm working through a class assignment and I'm not sure how to remove an element from an array. I've read suggestions to use ArrayUtils or convert the array to a linked list. I'm still very new to Java, so I'm not sure if I actually need to do something like this or if I'm overlooking something that's much simpler. I also need to complete a couple of processes that require skipping all null elements in the array. I don't have a great professor and communication attempts are futile, so I'm hoping someone here can help. My code follows. The relevant bits begin at "public void remove". I'm just posting all of the code in this class to give a fuller picture of what's going on:
public class WatchCollection
{
private Watch watches[]; // an array of references to Watch objects
// watches[i] == null if there is no watch in position i
private int num; // size of the array
private void init(int numberOfWatches) {
watches = new Watch[numberOfWatches];
for (int i=0;i<numberOfWatches;++i)
{
watches[i] = null;
}
num = numberOfWatches;
}
public WatchCollection(int numberOfWatches)
{
init(numberOfWatches);
}
public WatchCollection (Watch w1)
{
init(1);
add(w1);
}
// TODO Define WatchCollection (Watch w1, Watch w2) constructor
public WatchCollection (Watch w1, Watch w2)
{
}
// TODO Define WatchCollection (Watch w1, Watch w2, Watch w3) constructor
public WatchCollection (Watch w1, Watch w2, Watch w3)
{
}
public void add ( Watch w )
{
for(int i=0;i<num;++i)
{
if (watches[i]==null)
{
watches[i]=w;
return;
}
}
}
public void remove ( Watch w )
{
// TODO Write a code that removes Watch w if it is in the array
}
public int size()
{
// TODO Write a code that returns actual number of watches, skip all null array elements
}
public Watch at( int index)
{
// TODO Write a code that returns a watch with the specified index (skip all null array elements)
// TODO Throw an exception if the index is < 0 or >= actual number of watches
// For example, if the array contains w1 w2 null w3 w4
// index 0 -> w1
// index 1 -> w2
// index 2 -> w3
// index 3 -> w4
// index 4 -> an exception
}
public String toString()
{
String str="{\n";
int index=0;
for(int i=0;i<num;++i)
{
if (watches[i]!=null)
{
str+=" " +index++ + ": " +watches[i] + "\n";
}
}
str+=" }";
return str;
}
}
ArrayList is a builtin class that offers indexed access to elements, the ability to remove arbitrary elements, and dynamic expansion.
Since this is a class assignment, I'll just provide the algorithm to implement a remove method in your array (assuming this is an algorithm course):
function remove (Element element)
int index <- -1
for i <- 0 to num - 1
if (array[i] is equals to element) then
index <- i
break
end if
end for
if index > -1 then
for i <- index to num - 2
array[i] <- array[i+1]
end for
num <- num - 1
end if
end function
If this is an exercise about Java programming, it would be better to declare an ArrayList and use it since it already implements all these methods for you.
Without giving you the answer, here is how you could improve when you have.
public class WatchCollection {
private Watch watches[]; // an array of references to Watch objects
// watches[i] == null if there is no watch in position i
private int num = 0; // size of the array used.
public WatchCollection(int numberOfWatches) {
watches = new Watch[numberOfWatches];
}
public WatchCollection(Watch w1) {
this(1);
add(w1);
}
public void add(Watch w) {
if (watches.length == num + 1)
watches = Arrays.copyOf(watches, num*2);
watches[num++] = w;
}
You should try to keep your solution as simple as possible.
Here All you want is dealing with a Watch objects, so you don't need to use array.
Using ArrayList
is the best way to do your work.
This class has methods for accessing indexed elements, removing indexed element, dynamic expansion of the array etc.
The link leads to the official documentation for the ArrayList class.
Use Arraylist instead of array. if you already have an array, convert that to A