WHY there is an ArrayIndexOutOfBounds Exception ..Please Clarify :)
I have tried changing the size of the array but still I am unable to create successful program
import java.util.Scanner;
class insert
{
public static void main(String[]args) throws Exception
{
Scanner sc = new Scanner(System.in);
int a[]= new int[5];
int i;
for(i=0;i<a.length-1;i++)
{
System.out.println("Enter the Element : ");
a[i]=sc.nextInt();
}
System.out.println("Enter the location for insertion : ");
int loc = sc.nextInt();
System.out.println("Enter the value for location : " +loc+" is");
int value = sc.nextInt();
for(i=a.length-1;i>loc;i--)
{
a[i+1]=a[i];
}
a[loc-1] = value;
System.out.println("New Array is : ");
for (i=0;i<=a.length-1;i++)
{
System.out.println(a[i]);
}
}
}strong text
In this part:
for(i=a.length-1;i>loc;i--)
{
a[i+1]=a[i];
}
On the first iteration, a[i+1] is the same as a[a.length], but the last element in array is a[a.length-1], becausefirst element is a[0] and last one is a[length-1], in total a.length number of elements. So modify your loop accordingly.
One side note, when you define a size of an array, you cannot change it. Size is immutable. So you cannot insert an element and try to shift all the elements, because you need to increase the size with 1, which is not possible.
For this scenario, use ArrayList<Integer>>. ArrayList size increases as you add new elements
It is this for loop throwing the RuntimeException
for(i=a.length-1;i>loc;i--) {
a[i+1]=a[i];
}
You are trying to set the value of i + 1 element of the array, which is not existing.
/* Inserting an element in an array using its Index */
import java.util.*;
public class HelloWorld{
public static void main(String []args){
int[] a = {1,2,3,4,5};
int[] b = new int[a.length + 1];
int index = 2;
int element = 100;
System.out.println("The original array is: "+ Arrays.toString(a));
// In this for loop we iterate the original array from the front
for (int i = 0; i<index; i++){
b[i] = a[i];
}
// Here we insert the element at the desired index
b[index] = element;
// In this for loop we start iterating the original array from back.
for (int i = a.length; i>index; i--){
b[i] = a[i-1];
// b[3] = a[2];
}
System.out.println("The new Array is: " + Arrays.toString(b));
}
}
Output:
The original array is: [1, 2, 3, 4, 5]
The new Array is: [1, 2, 100, 3, 4, 5]
Related
Can't printout the indexes for all the elements with the same value from an array list. Only the index for the first element found in the array list is printed out.
Current output when list = 5,5,4,5:
Number 5 can be found in the following indexes [0, 0, 0, 0]
The desired output would be:
Number 5 can be found in the following indexes [0, 1, 3]
How I would want the code to work is that the user has to enter integers to an array list until the value -1 is entered. After that system prints out "What number are you looking for?". User enters the number for the element(s) that is wanted to be fetched from the array list. After that system prints out "Number 5 can be found in the following indexes [0, 1, 3].
Here's my code so far:
import java.util.ArrayList;
import java.util.Scanner;
public class sandbox{
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
ArrayList<Integer> list = new ArrayList<>();
while (true) {
int read = Integer.valueOf(reader.nextLine());
if (read == -1) {
break;
}
list.add(read);
}
System.out.print("What number are you looking for? ");
int requestednumb = Integer.valueOf(reader.nextLine());
int count = 0;
ArrayList<Integer> index = new ArrayList<>();
while ((list.size() > count)) {
if (list.contains(requestednumb))
;
index.add(list.indexOf(requestednumb));
count++;
}
System.out.println("Number " + requestednumb + " can be found in the following indexes " + index);
}
}
`
I'm pretty sure that it's an silly beginner mistake I have made, but after being stuck with this problem for multiple hours, I hope you can find the time to help me with this.
Use for loop to change the index and check the number at the given index:
for (int i = 0, n = list.size(); i < n; i++) {
if (list.get(i) == requestednumb) { // check the number at index i
index.add(i); // store the index
}
}
Or, with while loop and count used as the index:
int count = 0;
ArrayList<Integer> index = new ArrayList<>();
while (count < list.size()) {
if (list.get(count) == requestednumb) {
index.add(count);
}
count++;
}
Try this.
static <T> List<Integer> findIndices(List<T> list, T key) {
return IntStream.range(0, list.size())
.filter(i -> list.get(i).equals(key))
.boxed().toList();
}
public static void main(String[] args) {
List<Integer> list = List.of(5, 5, 4, 5);
System.out.println(findIndices(list, 5));
}
output:
[0, 1, 3]
very new to java and oop in general. so be kind.
I have one text file which contains 10 integers, searchkeysArray.txt. The program creates an array named keysArr. I have another text file of 500 random integers, array1.txt. The program creates another array named array1.
I want to use the linearSearch method I created to search for the elements of keysArr within array1 and output the index which it exist.
public static int linearSearch(int arr[], int x)
{
int size = arr.length;
for(int i = 0; i < size; i++)
{
if(arr[i] == x)
return i;
}
return -1;
}
readFile method
public static int[] readFile(String file)
{
try {
File f = new File(file);
Scanner s = new Scanner(f);
int ctr = 0;
while (s.hasNextInt())
{
ctr++;
s.nextInt();
}
int[] arr = new int[ctr]; //create array of that size
Scanner scanner2 = new Scanner(f);
for (int i = 0; i < arr.length; i++)
arr[i] = scanner2.nextInt();
return arr;
}
catch(Exception e)
{
return null;
}
the program.
public static void main(String[] args)
{
int[] keysArr = readFile("searchkeysArray");
int[] array1 = readFile("array17");
int key = 34;
int result = linearSearch(array1, key);
if (result != -1)
System.out.print("The element " +key+" is present in the array, at index " + result + " ");
else
System.out.print("The element " +key+" is not present in the array ");
}
and it outputs
The element 34 is present in the array, at index 359
which makes sense. I've manually tested numbers and (apparently) everything works fine. But I do not quite understand how I'm supposed to use keysArr as my key rather than int x = some number.
Want to output something like
The element [keysArr[0]] is present in the array, at index 359
The element [keysArr[1]] is present in the array, at index 547
...
The element [keysArr[4]] is not present in the array
and so on.
Right now keysArr just an array of 10 integers but I will eventually use hundreds..
Rather than using a specific hard-coded key, such as int key = 34, you wish to loop over your array of keys keysArr. You can achieve that by using code like:
for (int key : keysArr) {
int result = linearSearch(array1, key);
if (result != -1)
System.out.print("The element " +key+" is present in the array, at index " + result + " ");
else
System.out.print("The element " +key+" is not present in the array ");
}
Your linear algorithm worth O(n^2) which is pretty bad if you are going to increase the number of integers.
I suggest you to load dictionary elements into a hash-map Value -> Index and iterate through the values array looking up for the position in the hashMap. This will give you O(2n) - the complexity will be linear. You'll require 2n of memory though. But in your case it is insignificant.
public static void main(String[] args) {
printResults(new int[]{1, 2, 3, 4}, new int[]{3, 4, 7, 9});
}
public static void printResults(int dictionary[], int valuesToSearch[]){
Map<Integer, Integer> positionsMap = new HashMap<>();
IntStream.range(0, dictionary.length).forEach(index -> positionsMap.put(dictionary[index], index));
Arrays.stream(valuesToSearch).mapToObj(value -> positionsMap.containsKey(value) ?
format("Value %s is present in the array at index %s", value, positionsMap.get(value)) : format("Value %s is not present in the array", value)
).forEach(System.out::println);
}
Can you explain some lines below please ( I put ? in front of each line that needed to be explained). Thanks in advance !
I know that :
Merge-sort on an input sequence S with n elements consists of three steps:
Divide: partition S into two sequences S1 and S2 of about n/2 elements each
Recur: recursively sort S1 and S2
Conquer: merge S1 and S2 into a unique sorted sequence
But when I read the code I lost my way, can you just guid me please.
public class MergeSort {
public static int[] mergeSort(int [] list) {
if (list.length <= 1) {
return list;
}
// Split the array in half
int[] first = new int[list.length / 2]; // ok
int[] second = new int[list.length - first.length]; // ?
System.arraycopy(list, 0, first, 0, first.length); // ?
System.arraycopy(list, first.length, second, 0, second.length); // not sure ?
// Sort each half
mergeSort(first); // ok
mergeSort(second); // ok
// Merge the halves together, overwriting the original array
merge(first, second, list); // ok
return list; // ok
}
private static void merge(int[] first, int[] second, int [] result) { // explain in general ?
// Merge both halves into the result array
// Next element to consider in the first array
int iFirst = 0;
// Next element to consider in the second array
int iSecond = 0;
// Next open position in the result
int j = 0;
// As long as neither iFirst nor iSecond is past the end, move the
// smaller element into the result.
while (iFirst < first.length && iSecond < second.length) { // ??!!
if (first[iFirst] < second[iSecond]) {
result[j] = first[iFirst];
iFirst++;
} else {
result[j] = second[iSecond];
iSecond++;
}
j++;
}
// copy what's left
System.arraycopy(first, iFirst, result, j, first.length - iFirst);
System.arraycopy(second, iSecond, result, j, second.length - iSecond);
}
public static void main(String args[]) throws Exception
{
String list="";
int i=0,n=0;
MergeSort s= new MergeSort();
ArrayList<Integer> arrlist=new ArrayList<Integer>();
System.out.println(" ");
System.out.println(" ");
System.out.println("Please enter the list of elements,one element per line");
System.out.println(" write 'STOP' when list is completed ");
BufferedReader bf=new BufferedReader(new InputStreamReader(System.in));
while(!(list=bf.readLine()).equalsIgnoreCase("stop")){
int intelement=Integer.parseInt(list);
arrlist.add(intelement);
}
int elementlist[] = new int[arrlist.size()];
Iterator<Integer> iter = arrlist.iterator();
for (int j=0;iter.hasNext();j++) {
elementlist[j] = iter.next();
}
elementlist=mergeSort(elementlist); // ?
System.out.println(" ");
System.out.println(" ");
System.out.println(" ");
System.out.println("Values after Merge Sort : ");
for (int j=0;j<elementlist.length;j++) {
System.out.println(elementlist[j]+" ");
}
}
}
In int[] first = new int[list.length / 2]; and int[] second = new int[list.length - first.length]; method is dividing the list into 2 arrays, lets say your list has a length of 5 first will have 2 as its size and 3 for second. In
System.arraycopy(list, 0, first, 0, first.length);
System.arraycopy(list, first.length, second, 0, second.length);
your populating both first and second arrays from your list array( copy list[0],list[1] to first array and list[2],list[3],list[4] to second array).
In private static void merge(int[] first, int[] second, int [] result) you are merging first and second arrays and overwriting the result array
in the while loop you take the first element of first and second arrays and comparing them and move the smallest to result[0] then increment the pointer to arrays accordingly by using if and else statements and now you have the smallest element in both first and second arrays placed in result[0] .
You increment j ,it means in this iteration you will put the second smallest element in result[1] and so on.
In elementlist=mergeSort(elementlist); you are sorting elementlist by invoking your mergeSort(int [] list); method.
Given an array of ints, I want to rearrange it alternately i.e. first element should be minimum, second should be maximum, third second-minimum, fourth second-maximum and so on...
I'm completely lost here...
Another method that doesn't require the space of three separate arrays but isn't as complex as reordering in place would be to sort the original array and then create a single new array. Then start iterating with a pointer to the current i-th index of the new array and pointers starting at the 0-th index and the last index of the sorted array.
public class Foo {
public static void main(String[] args) {
// Take your original array
int[] arr = { 1, 4, 5, 10, 6, 8, 3, 9 };
// Use the Arrays sort method to sort it into ascending order (note this mutates the array instance)
Arrays.sort(arr);
// Create a new array of the same length
int[] minMaxSorted = new int[arr.length];
// Iterate through the array (from the left and right at the same time)
for (int i = 0, min = 0, max = arr.length - 1; i < arr.length; i += 2, min++, max--) {
// the next minimum goes into minMaxSorted[i]
minMaxSorted[i] = arr[min];
// the next maximum goes into minMaxSorted[i + 1] ... but
// guard against index out of bounds for odd number arrays
if (i + 1 < minMaxSorted.length) {
minMaxSorted[i + 1] = arr[max];
}
}
System.out.println(Arrays.toString(minMaxSorted));
}
}
Hint:
Create two new arrays, 1st is sorted in assenting order and other is in descending order. Than select 1st element from 2nd array and 1st element from 1st array, repeat this selection until you reach half of both 1st and second array. and you will get your desired array.
Hope this will help you.
The approach in #Kaushal28's answer is the best approach for a beginner. It requires more space (2 extra copies of the array) but it is easy to understand and code.
An advanced programmer might consider sorting the array once, and then rearranging the elements. It should work, but the logic is complicated.
Hint: have you ever played "Clock Patience"?
This solution is based on Aaron Davis solution. I tried to make the looping easier to follow:
public class AltSort {
//list of array elements that were sorted
static Set<Integer> indexSorted = new HashSet<Integer>();
public static void main (String[] args) throws java.lang.Exception
{
//test case
int[] array = new int[]{7,22,4,67,5,11,-9,23,48, 3, 73, 1, 10};
System.out.println(Arrays.toString(altSort(array)));
//test case
array = new int[]{ 1, 4, 5, 10, 6, 8, 3, 9 };
System.out.println(Arrays.toString(altSort(array)));
}
private static int[] altSort(int[] array) {
if((array == null) || (array.length == 0)) {
System.err.println("Empty or null array can not be sorted.");
}
Arrays.sort(array);
//returned array
int[] sortedArray = new int[array.length];
int firstIndex = 0, lastIndex = array.length-1;
for (int i = 0; i < array.length; i++) {
if((i%2) == 0) { //even indices
sortedArray[i] = array[firstIndex++];
}
else {
sortedArray[i] = array[lastIndex --];
}
}
return sortedArray;
}
}
Here is another alternative: monitor the indices that have been sorted, and search the rest for the next min / max:
import java.util.Arrays;
import java.util.Set;
/**
* Demonstrates an option for sorting an int[] array as requested,
* by keeping a list of the array indices that has been sorted, and searching
* for the next min / max.
* This code is not optimal nor robust. It serves a demo for this option only.
*
*/
public class AltSort {
//list of array elements that were sorted
static Set<Integer> indexSorted ;
public static void main (String[] args) throws java.lang.Exception {
//test case
int[] array = new int[]{7,22,4,67,5,11,-9,23,48, 3, 73, 1, 10};
System.out.println(Arrays.toString(altSort2(array)));
//test case
array = new int[]{ 1, 4, 5, 10, 6, 8, 3, 9 };
System.out.println(Arrays.toString(altSort2(array)));
}
private static int[] altSort2(int[] array) {
if((array == null) || (array.length == 0)) {
System.err.println("Empty or null array can not be sorted.");
}
//returned array
int[] sortedArray = new int[array.length];
//flag indicating wether to look for min or max
boolean lookForMin = true;
int index = 0;
while(index < array.length) {
if(lookForMin) {
sortedArray[index] = lookForArrayMin(array);
}else {
sortedArray[index] = lookForArrayMax(array);
}
index++;
//alternate look for min / look for max
lookForMin = ! lookForMin;
}
return sortedArray;
}
private static int lookForArrayMin(int[] array) {
int minValue = Integer.MAX_VALUE;
int minValueIndex = 0;
for( int i =0; i< array.length; i++ ){
//if array[i] is min and was not sorted before, keep it as min
if( (array[i]< minValue) && ! indexSorted.contains(i) ) {
minValue = array[i]; //keep min
minValueIndex = i; //keep min index
}
}
//add the index to the list of sorted indices
indexSorted.add(minValueIndex);
return minValue;
}
private static int lookForArrayMax(int[] array) {
int maxValue = Integer.MIN_VALUE; //max value
int maxValueIndex = 0; //index of max value
for( int i =0; i< array.length; i++ ){
//if array[i] is max and was not sorted before, keep it as max
if( (array[i] > maxValue) && ! indexSorted.contains(i)) {
maxValue = array[i]; //keep max
maxValueIndex = i; //keep max index
}
}
//add the index to the list of sorted indices
indexSorted.add(maxValueIndex);
return maxValue;
}
}
I was trying out a programming challenge I found, you can find it here if you want to know exactly what the requirements are, but what i'm basically trying to do is to get the lowest possible multiple of a Fibonacci Sequence that contains a given number. So input 13 would output [0, 1, 1, 2, 3, 5, 8, 13]. Input 6 would output [0, 2, 2, 4, 6].
My code works fine for any number in the regular Fibonacci Sequence but for any multiple it just outputs, for exmple if the input is 16, [0, 16] and I can't quite figure out why. Any help would be massively appreciated.
import java.util.Scanner;
import java.util.ArrayList;
public class FibonacciMultiples{
public static void main(String args[]){
int target;
ArrayList<Integer> x = new ArrayList<Integer>();
x.add(0);
Scanner input;
input = new Scanner(System.in);
System.out.println("Please enter target: ");
target = input.nextInt();
int i = 0;
int j = 1;
int k = 1;
while(x.get(i) != target){
x.add((j*k) + x.get(i));
i++;
j = x.get(i-1);
if(x.get(i) > target){
x.clear();
x.add(0);
i=0;
j=1;
k++;
}
};
System.out.println(x);
}
}
The problem is here :
j = x.get(i-1);
You take the j for the next iteration from the list, which means it's already multiplied by k.
Then you multiply it again by k here :
x.add((j*k) + x.get(i));
One way to fix it is change
j = x.get(i-1);
to
j = x.get(i-1)/k;
EDIT :
A much more elegant solution with no multiplications or divisions :
while(x.get(i) != target){
x.add(j + x.get(i));
i++;
j = x.get(i-1);
if(x.get(i) > target){
x.clear();
x.add(0);
i=0;
j=k; // this is the key
k++;
}
};
Now the first elements in the sequence are initialized to 0 and k, which means each element will be k times larger than the corresponding element in the original sequence.
Output for 16 :
[0, 2, 2, 4, 6, 10, 16]
an even more elegant solution (IMO) is this:
public static void main(String[] args)
{
int target;
Scanner input;
input = new Scanner(System.in);
System.out.println("Please enter target: ");
target = input.nextInt();
List<Integer> fibonacciList = new ArrayList<>();
int f1 = 1; // f1 starts at 1 and is increased until found a match
do {
fibonacciList = fibonacci(f1++, target);
} while (fibonacciList.get(fibonacciList.size()-1) != target);
System.out.println(fibonacciList);
}
// calculate fibonacci with given f(1) value until
// target is reached (or passed)
public static List<Integer> fibonacci(int f1, int target)
{
List<Integer> fibonacciList = new ArrayList<>();
// seed the list with given arg
fibonacciList.add(0);
fibonacciList.add(f1);
while (fibonacciList.get(fibonacciList.size()-1) < target) {
// build the list by adding last two items
fibonacciList.add(
fibonacciList.get(fibonacciList.size()-2) +
fibonacciList.get(fibonacciList.size()-1));
}
return fibonacciList;
}