public static void countingSort(Integer[] a, int n) {
//TODO
//COMPLETE THIS METHOD
int[] counter = new int[n+1];
int[] sorted = new int[a.length];
Arrays.fill(counter,0);
// fills counter array with each number count
for ( int i = 0 ; i < a.length; i++){
counter[a[i]] += 1;
} // adds n-1 index + n index
for (int i = 1; i < counter.length; i++) {
counter[i] = (counter[i] + counter[i-1]);
} // shifts array to the right
for (int i = counter.length-1; i > 0; i--) {
counter[i] = counter[i-1];
} // fills sorted array with the sorted out counts
for (int i = 0; i < a.length; i++ ){
sorted[counter[a[i]]] = a[i];
counter[a[i]]++;
}
}
When ran it throws an array out of bound exception in the body of the first for loop. Im having trouble seeing it, if anyone could help guide me, it'd be much appreciated.
When ran it throws an array out of bound exception in the body of the
first for loop.
That would be this:
for ( int i = 0 ; i < a.length; i++){
counter[a[i]] += 1;
}
Im having trouble seeing it, if anyone could help
guide me, it'd be much appreciated.
An ArrayIndexOutOfBoundsException in that loop can only mean that you are exceeding the bounds of a or those of counter. It is clear from inspection that you are not exceeding the bounds of a (though you could both eliminate that possibility and make the code a bit cleaner by switching to an enhanced for loop). The only remaining possibility is that you are exceeding the bounds of counter.
The approach you've implemented supports only non-negative integers in the input array, and requires the method invoker to pass an upper bound on the element values as the second parameter. If those constraints are not satisfied then an exception such as you observe will be thrown.
That is, if the exception is thrown where you say it is, then the problem is with the input.
Related
I have an atomic integer array of size 10. I am using this array to organize numbers 1-10 sent in by threads. This 1-10 will eventually be able to change to be a range of numbers larger than 10 and the list is to contain the 10 greatest numbers in that range. I can see the numbers going into the loops and recognizing that they are greater than a number currently there. However, there is never more than 2 numbers in the array when it is printed out. I have tried to trace my code in debug mode, however, it looks as if it is working as intended to me. I feel like there may be a simple error to my logic? I am completely sure all values are entering in the function as I have triple checked this. I start at the end of the array which should contain the highest value and then swap downwards once the slot has been determined. I would appreciate the assistance. This is just a simple experiment I am doing in order to grasp the basics before I try to tackle a homework assignment.
Here an example of my code:
public class testing{
static AtomicIntegerArray maxList = new AtomicIntegerArray(10);
final static int n = 10;
static void setMax(int value)
{
for(int i = 9; i >= 0; i--)
{
if(value > maxList.get(i))
{
int temp = maxList.get(i);
maxList.set(i,value);
if(i == 0)
{
maxList.set(i, value);
}
else
{ for(int j = i-1; j > 0; j--)
{
maxList.set(j, temp);
temp = maxList.get(j-1);
}
}
break;
}
}
public static void main(String[] args)
{
for (int i = 0; i < n; i++)
{
setMax(i);
}
}
}
Here is an example of how it is being called:
Brooke, there is a small bug in your 'j' loop. You had saved the state of a variable (temp), however your logic in the j loop lost the state. This new logic preserves the state of the previous element in the list.
Try this:
for (int j = i - 1; j >= 0; j--) {
int t2 = maxList.get(j);
maxList.set(j, temp);
temp = t2;
}
So as part of a task, I was asked to create an array with randomized values within a range, and then to sort it from smallest to biggest (I used a bubble sort), and then to firstly, print the sum of all the elements in the array, then to list them from smallest to biggest.
My issue is that I keep getting the ArrayIndexOutOfBoundsException error, but cannot find where this problem lies.
You can see in the code that I've put in the randomArrays method, a for loop that creates the random values for the array size I declared in the main method, then, underneath the for loop, I've created an if statement that checks to see if an element's value is bigger than the element after it, if it is, it swaps the place of the elements, until they're all sorted into smallest to biggest, and the loop is terminated.
Any help is much appreciated, thank you :)
public class MyArray {
public static void main(String[] args) {
int[] elements = new int[50];
int min = 0;
int max = 50;
randomArrays(elements, max, min);
}
public static void randomArrays(int[] elements, int max, int min) {
int range = max - min; //defines the range of the integers
int temp;
boolean fixed = false;
while (fixed == false) {
fixed = true;
for (int i = 0; i < elements.length; i++) {
elements[i] = min + (int) (Math.random() * range);
while (i < elements.length) {
if (elements[i] > elements[i + 1]) {
//if 8 > 5
temp = elements[i + 1];
//store 5 in temp
elements[i + 1] = elements[i];
//put the 8 in the 5's place
elements[i] = temp;
fixed = false;
}
i++;
}
}
}
}
//System.out.println(elements[i]);
}
My issue is that I keep getting the ArrayIndexOutOfBoundsException
error, but cannot find where this problem lies.
Problem lies in the condition of the for loop. You get ArrayOutOfBounds exception when i=49 and then you try to access i+1 index which doesn't exists.
Change
for (int i = 0; i < elements.length; i++)
to
for (int i = 0; i < elements.length-1; i++)
As you can already see that your code is going out of the arrays limit.
if you look at your code, following is where this is happening
while (i < elements.length) {
Its this while loop part, so if you change it to correctly loop thru the right number of elements, your problem will be resolved..change your while loop code with this one
while (i < elements.length-1) {
My textbook gave me this code to help count the amount of times a certain number shows up in an array of integers. I tried to apply the code my textbook gave me to my assignment but it doesn't seem to be working. Basically, I have to generate 30 random integers in an array, with the upper bound being 15 and lower bond being -5.
I want to find out how many times a number in the array is equal to 0, 1, 2... all the way until 10. The first code is the one my textbook gave me. They also used a random number generator but instead of finding how many elements is equal to 0, 1, etc, they want to find how many times each number appears. (The scores array is simply the random number generator, and their upper bound is 100). The second code is mine.
int[] counts = new int [100];
for (int i = 0; i < scores.length; i++) {
int index = scores[i];
counts[index]++;
}
//This is my code
public static void main(String[] args) {
int []a = arrayHist ();
printArray (a);
}
public static int randomInt (int low, int high) {
int range = (high - low) +1;
return (int) (Math.random() * range) + low;
}
public static int[] randomIntArray (int x) {
int[] random = new int[x];
for (int i = 0; i< x; i++) {
random [i] = randomInt (-5, 15);
}
return random;
}
public static int[] arrayHist () {
int[] counts = new int [30];
int[] hist = randomIntArray (30);
for (int i = 0; i < 10 && i >= 0; i++) {
int index = hist[i];
counts[index]++;
}
return hist;
}
public static void printArray (int[] a) {
for (int i = 0; i < a.length; i++) {
System.out.println (a[i]);
}
}
I'm supposed to be getting only 11 elements, but instead I get 30 random numbers again. Why is that?
I'll put some comments in your code, and see if you can spot where it goes wrong:
//take a histogram of the array. We're only going to count values between 0 and 10
//so 25th to 75 centiles, ignoring values that are lower than 0 or higher than 10
public static int[] arrayHist () {
//need to make an array of 11 numbers for the counts
int[] counts = new int [30];
//get an array of 30 random numbers
int[] hist = randomIntArray (30);
//loop over the whole array of 30 numbers
for (int i = 0; i < 10 && i >= 0; i++) {
//retrieve the random number into a variable temporarily
int index = hist[i];
//if the value is too low or too high, skip it
//else, store it in the counts array - the value from the random array
//serves as the index position in the counts array
counts[index]++;
}
//return the counts array
return hist;
}
What I've done with my comments is equivalent to designing the algorithm using the language you think in (English) and then you can translate it into the language you're learning (java). Very few developers think in the programming language they write. As a student I recommend you should ALWAYS write comments to explain your algorithm to yourself before you write code underneath the comments. You get points for writing comments (usually) so if you write them first then a) it helps you write the code and b) you don't have the tedious job of writing comments after you get the code working
Please please, for your own good/learning, try working out what is wrong from the above before looking at the spoilers(answers) below. Roll the mouse over the box to display the spoilers
//loop over the whole array of 30 numbers - YOU ONLY LOOP 10
for (int i = 0; i < 10 && i >= 0; i++) {
//if the value is too low or too high, skip it - YOU DIDN'T DO THIS CHECK
...
}
//return the counts array - YOU RETURNED THE WRONG ARRAY
return hist;
Edits in response to comments:
Checking a range
You'll have to check two limits, and hence it will need to be of one of the following forms:
if(x < 0 || x > 10) then don't do the count
if(!(x >= 0 && x <= 10)) then don't do the count
if(x >= 0 && x <= 10) then do the count
if(!(x < 0 || x > 10)) then do the count
Tests that use NOT - the exclamation mark ! - are typically a bit harder to read and understand, so try to avoid them is possible. Tests that are "positive minded" - i.e. they return a positive result rather than a negative that needs to be negated - are easier to read and understand.
A helpful tip for loops and methods, in terms of error checking, is to test for bad values that meet certain conditions, and if a bad value is encountered, then skip processing the rest of the loop (using the continue) keyword, or skip the rest of the method (by returning from it)
Doing this means that your if body (the bit between { and } ) doesnt get massive. Compare:
for(...){
if(test for bad values)
continue;
//50 lines long loop body
}
Is neater than doing:
for(...){
if(test for goodvalues){
//50 lines long loop body
}
}
If you use the bottom pattern, you can end up after several IFs in a real indented mess, with { and } all over the place and your code is way over to the right hand side of the screen:
for(...){
//code
if(...){
//code
if(...){
//code
if(...){
//code
if(...){
//code
if(...){
//code
if(...){
//code
}
//code
}
//code
}
//code
}
//code
}
//code
}
//code
}
Keeping indent levels to a minimum helps make your code more readable
Hence, I recommend in your case, that rather than test for the value being inside the range 0 to 10 and doing something with it, you adopt the form "if value is OUTSIDE" the range 0 to 10, skip doing the rest of the loop
Your arrayHist() method just returns the array with the random numbers. It should be more like this:
public static int[] arrayHist() {
// generate array with random numbers
int[] hist = randomIntArray(30);
// initialize the array for counting
int[] counts = new int[11];
// step through the random numbers array and increase corresponding counter if the number's values is between 0 and 10
for (int j = 0; j < hist.length; j++) {
int number = hist[j];
if (number > -1 && number < 11) {
counts[number]++;
}
}
return counts;
}
I need to create a Method that has 2 parameters in Java, upperborder and lowerborder. This method must create an array from the number 2 to the number 10.
Then I must implement another method, that calculates the factorial for a given number.
Then I must implement a third method that calculates the factorial for every element in the created array and test all these methods in a TestClass.
I know how to do this, but apparently I'm making some kind of a mistake in my code and it gives me the StackOverflow exception. I read the code a couple of times, but I can't seem to quite understand where I'm wrong.
package fakultaetinarray;
public final class FakultaetinArray{
private int i;
private int[] a;
private int j;
public FakultaetinArray(){
System.out.println("Given array : ");
createArray(1, 9);
System.out.println("Factorial for every element : ");
FakinArray();
}
public int fakRe(int n){
if(n == 1){
return n;
}
return n * fakRe(n - 1);
}
public void createArray(int untergrenze, int obergrenze){
this.a = new int[obergrenze];
for(this.j = 1; j <= a.length; j++){
a[i] = j + 1;
System.out.println(a[i]);
}
}
public void FakinArray(){
a[0] = 2;
for(i = 1; i < a.length; i++){
int fak = fakRe(a[i]);
a[i] = fak;
System.out.println(fak);
}
}
}
The reason you're getting StackOverflowErrors is due to your recursive method not having a case when n == 0.
The reason that your values are coming in as 0 is due to how you're constructing your loop.
for(this.j = 1; j <= a.length; j++){
a[i] = j + 1;
System.out.println(a[i]);
}
It's unclear why you're using j here at all, and i is initialized to its default value of 0, so in all reality, you're only ever filling one element of your array with a positive value and all of the others are at zero.
You need to reconsider how your loops are constructed. I would strongly encourage you not to make them fields, but declare them as part of the loop construct instead.
if(n == 1){ is not a strong enough condition to block the recursion: n can go below 1. In your particular case, you have a situation where n is 0.
Consider unwinding the recursion to a simple loop in any case. As a rule of thumb, recursion is not good for O(N) stuff.
Currently working on a student project. I want to figure out the highest number and sort it by bubble sort, the number is parsed from a JLabel, but I get this error everytime. Here is a code snippet:
JLabel[] wuerfelsummen = new JLabel[7];
wuerfelsummen[0] = player1_wuerfelsumme;
wuerfelsummen[1] = player2_wuerfelsumme;
wuerfelsummen[2] = player3_wuerfelsumme;
wuerfelsummen[3] = player4_wuerfelsumme;
wuerfelsummen[4] = player5_wuerfelsumme;
wuerfelsummen[5] = player6_wuerfelsumme;
public int ermittleGewinner(JLabel[] w)
{
int temp;
int[] zahlen = new int[w.length];
for(int i=0; i<=zahlen.length; i++)
{
if(w[i].getText() == null)
{
zahlen[i] = 99999999;
}
else
{
zahlen[i] = Integer.parseInt(w[i].getText());
}
}
for(int i=1; i<zahlen.length; i++)
{
for(int j=0; j<zahlen.length-i; j++)
{
if(zahlen[j]>zahlen[j+1])
{
temp=zahlen[j];
zahlen[j]=zahlen[j+1];
zahlen[j+1]=temp;
}
}
}
for(int i=0; i<=zahlen.length; i++)
This is incorrect, as arrays are 0-indexed, meaning they reach from 0 to length-1.
Change it to
for(int i=0; i<zahlen.length; i++)
Interestingly enough, your other loops avoid this pitfall, although you will still have to be careful about the j+1 later on. Make sure that this can never be >= zahlen.length.
You could simply initialize j with 1 instead of 0 and then replace all occurences of j with j-1 and j+1 with j
change "i<=zahlen.length" in your for loop to "i < zahlen.length".
remember arrays are 0 indexed so you are trying to access an element one index outside of how large your array is with the "<=" method you are currently using
The second loop should start at i=0 instead of i=1. By using i=1, you are again going to try to access one element past the size of your array
ArrayIndexOutOfBounds expcetion comes when code tried to access an element of an array which is not present. In your code, since you are FOR looping one extra time for(int i=0; i<=zahlen.length; i++), you are getting this exception. Keep FOR loop as for(int i=0; i<zahlen.length; i++)
You have not to just check for zahlen[i] but also for w[i] because you are looping on length of zahlen and it may so happen that w is of lesser length then zahlen.