Cyclic shift of numbers in an array (Java) - java

I need to perform a cyclic shift of the array elements to the left by n characters.
Here is my code:
public static void moveLeft(int[] arr, int num) {
int[] temp = new int[num];
for (int i = 0; i < num; i++) {
temp[i] = arr[i];
}
for(int i = arr.length - num; i > 0; i++) {
arr[i-num] = arr[i];
}
for (int i = 0; i < num; i++) {
arr[i] = temp[i];
}
}
When I run this code, I get this error: Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 10 out of bounds for length 10

for( ...; i > 0; i++) is very suspicious, that is, while i > 0 do increment i (if not starting with negative values, i will be incremented till it (silently) overflows or an Exception is thrown somewhere else).
{incrementing ++ requires an upper limit < value (or <=); decrementing -- a lower one > value (or >=) }
The code is accessing arr[i] (and arr[i-num]), so arr.length should be the limit (assuming non-negative num): i < arr.length
it is also the logical choice since it should copy all numbers from index num up to the end of the array.

Related

Can't understand why loop is not updating variable value

When I create this method to find the index of the smallest number in an array starting from a specific index, it keeps returning 0 no matter which numbers are in the array. It seems that index = i in the for loop is not updating the value of the index variable, even if the array contains other numbers lower than the 0 spot. Why?
public static int indexOfSmallestFrom(int[] array, int startIndex) {
int smallest = array[startIndex];
int index = 0;
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each < smallest) {
smallest = each;
index = i;
}
}
return index;
}
edit: Here's the main method:
public static void main(String[] args) {
// write your test code here
int[] array = {99, 3, 1, 7, 4, 5, 2, 4};
System.out.println("Smallest: " + indexOfSmallestFrom(array, 1));
}
It works correctly every time EXCEPT when the startIndex variable passed to the method call is 2! When a 1 is passed as above, it correctly returns 2, when 3 is passed, it correctly returns 6, etc. ???
Because when you pass startIndex = 2 into the function, we have smallest = array[startIndex] = 1 in this case, and your code initializes int index = 0;. However, in your for loop, you have:
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each < smallest) {
smallest = each;
index = i;
}
}
Since your smallest was initialized to the number at position startIndex but not your index, and the fact that startIndex happened to be the index of the smallest number, your if (each < smallest) will never be entered, meaning that index will stay at 0.
To fix this, either change int index = 0; to int index = startIndex; OR you can change the condition in the if statement to if (each <= smallest) and your code should work fine (note that if you do this, it will return the last index if multiple minimums are present in the array).
Your code works for me, may be the smallest value is in 0 place in your case. But you should change index = startingIndex. Because that is where you are comparing items from.
public static int indexOfSmallestFrom(int[] array, int startIndex) {
int smallest = array[startIndex];
int index = startIndex;
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each < smallest) {
smallest = each;
index = i;
}
}
return index;
}
Or change < to <=
public static int indexOfSmallestFrom(int[] array, int startIndex) {
int smallest = array[startIndex];
int index = 0;
for (int i = startIndex; i < array.length; i++) {
int each = array[i];
if (each <= smallest) {
smallest = each;
index = i;
}
}
return index;
}
Because the value in position 2 is the SMALLEST value (it's 1), hence the if condition is never entered :).

`nums[nums.length - 1]; ` is an range or single element?

I read such a solution to rotate an array
the question:
public class Solution {
public void rotate(int[] nums, int k) {
int temp, previous;
for (int i = 0; i < k; i++) {
previous = nums[nums.length - 1];
for (int j = 0; j < nums.length; j++) {
temp = nums[j];
nums[j] = previous;
previous = temp;
}
}
}
}
I am confused about previous = nums[num.lengh -1],
is it a range as nums[0:10] or a single element as nums[0]?
It's a single element, he is taking the element in the num.length -1 position, and the value inside is being swapped with nums[j]:
for j=0 you have:
temp = num[0];
num[0] = num[num.length-1]
num[num.length-1] = temp;
And so on.
It is a single element, because num.lengh - 1 is an int and just gives you the last accessible index of the array.
If you check wether the length of the array is > 0, then you can safely use the length of the array to determine the last accessible index.
The length of an array is very often used in loops like yours:
Here the length is used to make sure you don't access unavailable indexes:
for (int j = 0; j < nums.length; j++)
You can write slightly a different condition without changing the functionality
for (int j = 0; j <= nums.length - 1; j++)
But if you do the following, you will get an IndexOutOfBoundsException:
for (int j = 0; j <= nums.length; j++)
The last iteration would try to access nums[nums.length], which isn't there...
nums[nums.length - 1]; gives you the last position of the array. It is -1 cause the positions of an array starts with 0 not with 1.
If you don't write -1 you would get an Out of bounds exception.
single, this is due to you're performing a mathematical expression and then getting a valeu from that. meaning you're taking the length of the array list then subtracting 1 and then getting that value or in other words you're getting the last value.
to get all values you must loop like a for loop etc.
for (i = 0; i < array.length; i++) {
System.out.print(array[i]);
}

how to implement a descending selection sort in java?

i want to implement a selection sort method that takes an array of ints and sorts it in a descending order. however, the trick is to keep the original selection sort method unchanged but instead using simple arithmetic operations and without adding extra loops to swap the elements after the array finished sorting. this is my code and the idea is to store the position of the maximum value and the minimum value in local variables and swap them with the corresponding position after the inner loop finishes iteration. i even tried using a only one variable to find the lowest value and put it at the end of the array but i failed and i am getting the wrong results and i need help spotting the error. here is my code
public static void newSortMethod(int[]a){
for(int i = 0; i < a.length-1; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < a.length; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
if(a[j] > a[maxPosition]){
maxPosition = j;
}
}
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
System.out.println();
}
public static void swap(int[]a, int i, int j){
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void main(String[] args) {
int[] a = {2,6,3,9,5,4,8,7,0,13,-3,1};
newSortMethod(a);
}
here is the output of the program so far
-3 8 2 9 13 5 4 6 3 1 7 0
Your original algorithm is wrong. Firstly, the if blocks should compare to minPosition and maxPosition, not i. Secondly, if you are selecting both minimum and maximum, then your inner for loop should stop at a.length - i, not a.length (since the top i elements are also sorted). Doing both gives you this as the ascending order algorithm.
public static void newSortMethod(int[]a){
for(int i = 0; i < a.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < a.length - i; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
if(a[j] > a[maxPosition]){
maxPosition = j;
}
}
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
}
To switch to descending order, simply add one line.
public static void newSortMethod(int[]a){
for(int i = 0; i < a.length; i++){
int maxPosition=i;
int minPosition=i;
for(int j = i+1; j < a.length - i; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
if(a[j] > a[maxPosition]){
maxPosition = j;
}
}
swap(a,minPosition,maxPosition); // <-- this line
swap(a,maxPosition,i);
swap(a,minPosition,a.length-i-1);
}
}
Errors
First off, let’s look for problems in your code. There’s a few, which happens a lot in programming.
Your code is still trying to sort ascending with swap(a,minPosition,i), and then trying to put the maximum value at the end, which isn’t what you want: you want to put maximum values at the beginning.
Your n is never modified, so you’ll keep printing 0.
Sample solution
Now let’s see something that works. I’m not totally sure what your ascending selection sort looked like, but I imagine it should be something like this:
public static void ascendingSortMethod(int[]a){
int n = 0; // this is only to count how many times the swap method was called
for(int i = 0; i < a.length-1; i++){
int minPosition = i;
for(int j = i+1; j < a.length; j++){
if(a[j] < a[minPosition]){
minPosition = j;
}
}
if(minPosition != i){ // check whether swap is necessary
swap(a,minPosition,i);
n ++;
}
}
System.out.println(n);
}
To make it sort in descending order, just switch the comparison operator (and possibly the minPosition identifier for clarity).
public static void newSortMethod(int[]a){
int n = 0; // this is only to count how many times the swap method was called
for(int i = 0; i < a.length-1; i++){
int maxPosition = i;
for(int j = i+1; j < a.length; j++){
if(a[j] > a[maxPosition]){ // switched comparison operator
maxPosition = j;
}
}
if(maxPosition != i){ // check whether swap is necessary
swap(a,maxPosition,i);
n ++;
}
}
System.out.println(n);
}

How to compare two arrays of different sizes?

So my task is to read a file line by line and store the integers into an array. Then to add the integers in spots 1-5, 2-6, 3-7 etc. and store those into a new array.
In array 1 there is 4 more values than array 2. I need to compare these Arrays and see if array1 is 0.999 bigger than array2.
If it is indeed larger, I need to print out the LOCATION of the number in the array 1.
Right now my problem is my code is outputting that every number is larger than the corresponding number in array 2.
Code:
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class Asgn7
{
public static void main(String[] args) throws FileNotFoundException
{
Scanner file = new Scanner(new File("asgn7data.txt"));
double[] array = new double[file.nextInt()];
double[] newArray = new double[array.length - 4];
double tempVal = 0;
int j = 0;
int count = 0;
while(file.hasNext())
{
for(int i = 0; i < array.length ; i++)
{
array[i] = file.nextInt();
}
for(j = 0; j < array.length - 4; j++)
{
for(int k = 0; k < 5; k++)
{
newArray[j] += array[j+k] / 5;
}
}
for(int i = 2; i < array.length; i++)
{
if(array[i] > (newArray[i-2] + 0.999));
{
count++;
tempVal = count;
}
System.out.println(tempVal);
}
}
}
}
The values which should be compared are from 3-13.
Judging by the picture, you are not placing the values in the correct index in the second array, or you are not matching the correct ones.
If you want it to look exactly like in the picture, the second array should be declared:
double[] newArray = new double[array.length - 2];
And the loop to fill it should be changed to:
for(j = 2; j < array.length - 2; j++)
{
for(int k = -2; k <= 2; k++)
{
newArray[j] += array[j+k] / 5;
}
}
This will put the averages in the third, fourth, fifth... elements in newArray. And now you can compare them directly:
for(int i = 2; i < array.length - 2; i++)
{
if(array[i] > (newArray[i] + 0.999))
{
count++;
tempVal = count;
}
System.out.println(tempVal);
}
If you want to save the two unused spaces, as you originally did, rather than responding exactly to the picture, then you should calculate the values as you originally did. But remember to compare each element to the one two places before it and stop 2 places before the end.
Instead of
for(int i = 2; i < array.length; i++)
use
for(int i = 2; i < array.length - 2; i++)
To print the location, your construct with the count and tempVal is unnecessary. You just need to print i+1. Also note that you have a ; after your if. This means it's an empty if, and the block after it is always performed. Never have a ; after an if, for, while etc.
Not clear with what you are asking for in your question but without questioning what's the logic, by just looking at your code:
for(int i = 2; i < array.length; i++)
{
if(array[i] > (newArray[i-2] + 0.999));
{
count++;
tempVal = count;
}
System.out.println(tempVal);
}
}
if you relocate the system.out line as follows, I think you will get what you expect as follows:
for(int i = 2; i < array.length - 2; i++)
{
if(array[i] > (newArray[i-2] + 0.999));
{
System.out.println(tempVal);
// count++;
// tempVal = count;
}
}
}
PS: Please note that I have also changed the boundary for the loop to stop iteration on 13th member of the array, instead of 15.
Are you sure you're parsing the numbers correctly?
See Java: Reading integers from a file into an array
Why don't you print them out after parsing for verification?
btw, this will overflow the index of the 2nd array (since it is created using new double[array.length - 4]):
for(int i = 2; i < array.length; i++)
so does your code run?

Sieve of Eratosthenes, ArrayIndexOutOfBoundsException, output is composite number

I tried writing a Sieve of Eratosthenes algorithm, I am getting an ArrayIndexOutOfBoundsException but I don't seem to understand why, if I change the limits, upon printing it only displays composite numbers, the code's below help if you can.
public static Boolean[] solution(int N) {
Boolean[] isPrime = new Boolean[N];
isPrime[0] = false;
for(int i = 1; i <= N; i++) {
isPrime[i] = true;
}
for(int i = 2; i <= N; i++) {
if(isPrime[i]== true) {
System.out.println(i);
for(int j = 2; (j * i) < N; j++) {
int k = j * i;
isPrime[k] = false;
}
}
}
return isPrime;
i <= N; cause the error
for(int i = 1; i <= N; i++) {
isPrime[i] = true;
}
for example
if N=4 then you get error when i=4. isPrime[4] cause OutOfBounds exception because length is 4.arrays are zero index based. so maximum index you can access is 3.isPrime[3]
you can avoid this error by changing loop to for(int i = 1; i < N; i++) {
however i'm not sure what is Eratosthenes algorithem is .i hope you can change your code keep in mind arrays are zero index based
Boolean[N] creates an array of N elements, so, since the indexes start from 0, the last index is N-1.
The error is caused by i<=N in the for loop

Categories