Array index out of bounds - java

Although I tried to solve the exception using break it still fails on the input "321". Code for bubble sort on hackerrank.
The error occurs on if(a[i+1]==n).
import java.io.*;``
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] a = new int[n];
for(int a_i=0; a_i < n; a_i++){
a[a_i] = in.nextInt();
}
// Write Your Code Here
int numSwaps=0;
for(int i=0;i<n;i++){
if(a[i+1]==n){ // error occurs here
break;
}
else{
if(a[i]>a[i+1]){
int temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
numSwaps++;
}
}
}
//firstElement=a[0];
//lastElement=a[n-1];
System.out.println("Array is sorted in"+" "+numSwaps+" "+"swaps."+"\n"+"First Element:"+" "+a[0]+"\n"+"Last Element:"+" "+a[n-1]);
}
}

Your condition i<n will overflow when i=n-1, because you are adding i+1, you are referencing the array out-of-bounds.
The fix is easy, however, change the condition to i<n-1.
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] a = new int[n];
for(int a_i=0; a_i < n; a_i++){
a[a_i] = in.nextInt();
}
// Write Your Code Here
int numSwaps=0;
for(int i=0;i<n-1;i++){
if(a[i+1]==n){
break;
} else if(a[i]>a[i+1]){
int temp=a[i];
a[i]=a[i+1];
a[i+1]=temp;
numSwaps++;
}
}
//firstElement=a[0];
//lastElement=a[n-1];
System.out.println("Array is sorted in"+" "+numSwaps+" "+"swaps."+"\n"+"First Element:"+" "+a[0]+"\n"+"Last Element:"+" "+a[n-1]);
}
Also, take bit of pride in code style; I did a couple touch-ups, but its far from clean.

Just change the condition in the for loop to I < n- 1, it occurs due to the I+1 in the swapping module in your Program..

Related

Code Works in IntelliJ but Not in Hackerrank Editor

I'm doing this question on hackerrank: https://www.hackerrank.com/challenges/ctci-bubble-sort/problem?h_l=interview&playlist_slugs%5B%5D=interview-preparation-kit&playlist_slugs%5B%5D=sorting
I wrote the solution in intellij, and it gives me the correct output there, but when I copied it over to the hackerrank ide, it gave me an error.
This is the code I'm talking about:
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
class Results {
/*
* Complete the 'countSwaps' function below.
*
* The function accepts INTEGER_ARRAY a as parameter.
*/
public static void countSwaps(List<Integer> a) {
int count = 0;
boolean flag = false;
while (!flag) {
flag = true;
for (int i = 0; i < a.size() - 1; i++) {
if (a.get(i) > a.get(i + 1)) {
int temp = a.get(i);
a.set(i, a.get(i + 1));
a.set(i + 1, temp);
flag = false;
count++;
}
}
}
System.out.println(String.format(
"Array is sorted in %d swaps.%n" +
"First Element: %d%n" +
"Last Element: %d%n",
count,
a.get(0),
a.get(a.size() - 1)));
}
public static class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(bufferedReader.readLine().trim());
List<Integer> a = Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(toList());
Results.countSwaps(a);
bufferedReader.close();
}
}
}
This is the error: could not find or load main class solution.
Do you have any idea why I'm getting this error here? How could I fix it.
You have put the Solution class within your Result class. HackerRank wants you to put the Solution class as its own class, like this:
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
class Results {
/*
* Complete the 'countSwaps' function below.
*
* The function accepts INTEGER_ARRAY a as parameter.
*/
public static void countSwaps(List<Integer> a) {
int count = 0;
boolean flag = false;
while (!flag) {
flag = true;
for (int i = 0; i < a.size() - 1; i++) {
if (a.get(i) > a.get(i + 1)) {
int temp = a.get(i);
a.set(i, a.get(i + 1));
a.set(i + 1, temp);
flag = false;
count++;
}
}
}
System.out.println(String.format(
"Array is sorted in %d swaps.%n" +
"First Element: %d%n" +
"Last Element: %d%n",
count,
a.get(0),
a.get(a.size() - 1)));
}
}
class Solution {
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(bufferedReader.readLine().trim());
List<Integer> a = Stream.of(bufferedReader.readLine().replaceAll("\\s+$", "").split(" "))
.map(Integer::parseInt)
.collect(toList());
Results.countSwaps(a);
bufferedReader.close();
}
}
Please, check your code syntax and read the error that the IDE gives you. It did explicitly tell you that Error: Could not find or load main class Solution and just a quick check on the automatic indentation would have shown you the issue.
Online Coding contest platforms generally require you to adhere to certain rules for submissions.
See: Sample Problem Statement
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public class Solution
{
/*
* Complete the 'countSwaps' function below.
*
* The function accepts INTEGER_ARRAY a as parameter.
*/
public static void countSwaps (List < Integer > a)
{
int count = 0;
boolean flag = false;
while (!flag)
{
flag = true;
for (int i = 0; i < a.size () - 1; i++)
{
if (a.get (i) > a.get (i + 1))
{
int temp = a.get (i);
a.set (i, a.get (i + 1));
a.set (i + 1, temp);
flag = false;
count++;
}
}
}
System.out.println (String.format ("Array is sorted in %d swaps.%n" +
"First Element: %d%n" +
"Last Element: %d%n",
count,
a.get (0), a.get (a.size () - 1)));
}
public static void main (String[]args) throws IOException
{
BufferedReader bufferedReader =
new BufferedReader (new InputStreamReader (System.in));
int n = Integer.parseInt (bufferedReader.readLine ().trim ());
List < Integer > a =
Stream.of (bufferedReader.readLine ().replaceAll ("\\s+$",
"").split (" ")).
map (Integer::parseInt).collect (toList ());
countSwaps (a);
bufferedReader.close ();
}
}
The error: could not find or load main class solution. means your main() method in the Solution class could not be accessed.

How to apply a method from my main file in my JUnit test?

Our assignment says we should "write the source code and test code for a function named sumArray that accepts an array of ints and returns the sum of all elements from the array".
I think I've got SumArray.java to return sum OK, but I'm struggling to apply my method to the test input. Any help please? TIA.
SumArray.java
package sumarray;
import java.util.Scanner;
public class SumArray {
private static int n, sum = 0;
public static int sumArray() {
Scanner s = new Scanner(System.in);
System.out.print("Enter no. of elements you want in array:");
n = s.nextInt();
int a[] = new int[n];
System.out.println("Enter the elements. (Press [return] after each one)");
for (int i = 0; i < n; i++) {
a[i] = s.nextInt();
sum = sum + a[i];
}
System.out.println("Sum:" + sum);
return sum;
}
public static void main(String[] args) {
sumArray();
}
}
SumArrayTest.java
package sumarray;
import org.junit.Test;
import static org.junit.Assert.*;
public class SumArrayTest {
public SumArrayTest() {
}
/**
* Test of main method, of class SumArray.
*/
#Test
public void testMain() {
System.out.println("main");
String[] args = null;
SumArray.main(args);
int[] intArray = new int[]{2, 3, 4};
int expectedResult = 9;
// int testResult = sumArray({2, 3, 4});
int testResult = SumArray sumArray(intArray);
assertEquals(expectedResult, testResult);
// fail("The test case is a prototype.");
}
}
Edit: I've tried to implement what's been suggested so far with some changes; really not sure of any of this is right; a lot of it is guesswork TBH.
package sumarray;
import java.util.Scanner;
public class SumArray {
private static int n, sum = 0;
public static int sumArray;
public static int sumArray(int[] arr) {
return sum;
}
public static SumArray input() {
Scanner s = new Scanner(System.in);
System.out.print("Enter no. of elements you want in array:");
n = s.nextInt();
int a[] = new int[n];
System.out.println("Enter the elements. (Press [return] after each one)");
for (int i = 0; i < n; i++) {
a[i] = s.nextInt();
sum = sum + a[i];
}
System.out.println("Sum:" + sum);
return new SumArray();
}
public static void main(String[] args) {
SumArray result = input();
System.out.println(result.sumArray(SumArray));
}
}
package sumarray;
import org.junit.Test;
import static org.junit.Assert.*;
public class SumArrayTest {
public SumArrayTest() {
}
#Test
public void testSumArray() {
System.out.println("main");
String[] args = null;
int[] intArray = new int[]{2, 3, 4};
int expectedResult = 9;
assertEquals(expectedResult, SumArray.sumArray(intArray));
// fail("The test case is a prototype.");
}
}
The only error I'm seeing currently is 'cannot find symbol' for SumArray in main.
package sumarray;
import java.util.Scanner;
public class SumArray {
private static int n, sum = 0;
public static int sumArray() {
Scanner s = new Scanner(System.in);
System.out.print("Enter no. of elements you want in array:");
n = s.nextInt();
int a[] = new int[n];
System.out.println("Enter the elements. (Press [return] after each one)");
for (int i = 0; i < n; i++) {
a[i] = s.nextInt();
sum = sum + a[i];
}
System.out.println("Sum:" + sum);
return sum;
}
public static void main(String[] args) {
sumArray();
}
}
The above is the original code you posted. Now, you say you get the correct output. Yes, here you do:
package sumarray;
import java.util.Scanner;
public class SumArray {
private static int n, sum = 0;
public static int sumArray() {
Scanner s = new Scanner(System.in);
System.out.print("Enter no. of elements you want in array:");
n = s.nextInt();
int a[] = new int[n];
System.out.println("Enter the elements. (Press [return] after each one)");
for (int i = 0; i < n; i++) {
a[i] = s.nextInt();
sum = sum + a[i];
}
System.out.println("Sum:" + sum);
return sum;
}
public static void main(String[] args) {
sumArray(); // this one will return the correct answer
sumArray(); // this one will not
}
}
The second one will return wrong data, because you don't reset the value of sum.
You should split the tasks: sumArray should receive an array, and should return the sum of the elements. Either you should change the name of the method, or change the implementation, that is what Mahmoud told you.
package sumarray;
import java.util.Scanner;
public class SumArray {
private static Scanner scan = new Scanner(System.in); // create this on class level, not every execution of your method
public static int[] buildArray(int elements) {
int[] arr = new int[elements];
for ( int i = 0; i < elements; i++ ) {
System.out.println("Enter element nr: " + (i+1));
arr[i] = scan.nextInt();
}
return arr;
}
public static int sumArray(int[] input) {
int sum = 0; // don't use a class level one. especially not a static one, it's value could be altered by another thread
for ( int in : input ) { // iterate over the array and add the values
sum += in; // this should be in -> each iteration we add the value of in (the element of the array) to sum
}
return sum;
}
public static void main(String[] args) {
System.out.println("Provide the size of the array: ");
int param = scan.nextInt();
int[] array = buildArray(param);
int result = sumArray(array);
System.out.println("The sum of the array is: " + result);
}
}
This approach will land you with far lesser issues. It also doesn't have static variables like n and sum in your class that might lead to wrong results.
The main() method is the entry point into the application, you shouldn't test the main() method. Instead, you should test the sumArray() method and compare the expected Vs. the actual returned value from the method.
As a side note, you can better pass the input array to the sumArray() method as a parameter instead of reading it from System.in within the method body.
So your method signature can look like this:
public static int sumArray(int[] arr). The client code which uses this method, which is the main method in your case (or the unit test) can pass the array without bothering the method how this input array was got.

getting error in Beautiful Binary String in hackerrank

I am solving Beautiful Binary String problem in hackerrank but getting error may be my logic is not correct below is problem
Question
below is my logic which is checking three if conditions for the given binary string '010'.It contains minimumSteps variable which is counting the number of '010'
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.regex.*;
public class Solution {
// Complete the beautifulBinaryString function below.
// static String b;
static int beautifulBinaryString(String b) {
int minimumSteps=0;
for(int i=0;i<b.length();)
{
if(b.charAt(i)=='0' && b.charAt(i+1)=='1' && b.charAt(i+2)=='0')
{
minimumSteps++;
if((i+3)<b.length())
{
i=i+3;
}
}
else
{
break;
}
}
return minimumSteps;
}
// static boolean containChar(int i)
// {
// if(b.charAt(i)=='')
// {
// }
// }
private static final Scanner scanner = new Scanner(System.in);
public static void main(String[] args) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(System.getenv("OUTPUT_PATH")));
int n = scanner.nextInt();
scanner.skip("(\r\n|[\n\r\u2028\u2029\u0085])?");
String b = scanner.nextLine();
int result = beautifulBinaryString(b);
bufferedWriter.write(String.valueOf(result));
bufferedWriter.newLine();
bufferedWriter.close();
scanner.close();
}
}
Java 8
Initial Thoughts: We could use a greedy approach and starting from the left everytime we see a 010 replace the last 0 with a 1 and
continue
Examples:
01010
01110 -> 1
0100101010
0110101010
0110111010
0110111011 -> 3
java 1.8
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int n = input.nextInt();
input.nextLine();
String s = input.nextLine();
int count= 0;
for(int i = 0; i < s.length()-2; i++)
{
if(s.charAt(i) == '0' && s.charAt(i+1) == '1' && s.charAt(i+2) == '0')
{
count++;
i += 2;
}
}
System.out.println(count);
}
}

Rounding off an arraylist to an integer array

I've been trying with this problem but couldn't wrap my head around it..
"Create a java method int [] roundoff (ArrayList input) that returns a new integer array containing all the input doubles correctly rounded off to integers."
This is where I got so far:
package javaProblem;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class TowMethods {
public static int[] roundOff(ArrayList<Double> input) {
int [] iL=new int[input.size()];
for (double i:iL) {
//input.get(i);
int n=(int) Math.round(i) ;
iL[n]=n;
}
System.out.print(Arrays.toString(iL));
return (iL);
}
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
ArrayList<Double> input1 = new ArrayList<Double>();
input1.add(2.3);
input1.add(1.3);
input1.add(3.35);
/* for (int i = 0; i < 3; i++) {
double num = keyboard.nextDouble();
input.add(num);
}*/
int[] iList = roundOff(input1);
System.out.println(Arrays.toString(iList));
}
}
for (int i = 0; i < input.size(); i++) {
iL[i] = (int)(Math.round(input.get(i)));
}
Instead of your loop in roundOff method
Please try to use meaningful names when you name your variables. Also inside the roundOff method instead of the foreach loop use a classic for loop and don't iterate through the freshly created integer array but over the ArrayList which you take as a parameter.
Here is the possible solution:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class TowMethods {
public static int[] roundOff(ArrayList<Double> inputs) {
int [] integers=new int[inputs.size()];
for (int i=0; i < inputs.size(); i++) {
integers[i] = (int) Math.round(inputs.get(i));
}
return integers;
}
public static void main(String[] args) {
// Scanner keyboard = new Scanner(System.in);
ArrayList<Double> inputs = new ArrayList<Double>();
inputs.add(2.3);
inputs.add(1.3);
inputs.add(3.35);
/*
for (int i = 0; i < 3; i++) {
double num = keyboard.nextDouble();
inputs.add(num);
}
*/
int[] iList = roundOff(inputs);
System.out.println(Arrays.toString(iList));
}
}
If you want to take the user input just uncomment the commented lines in the main method.
Use Math.rint() which properly rounds to the next int value.
double [] dbls = {2.4, 8.8, 22.23, 97.6};
int[] ints = new int[dbls.length];
for (int i = 0; i < dbls.length; i++) {
ints[i] = (int)Math.rint(dbls[i]);
}
System.out.println(Arrays.toString(dbls));
System.out.println(Arrays.toString(ints));
Prints
[2.4, 8.8, 22.23, 97.6]
[2, 9, 22, 98]

NZEC Prime number Generation SPOJ- http://www.spoj.com/problems/PRIME1/

I am beginner at coding. I am getting NZEC error on submission of my code for prime number genertaion to spoj. But the code is working perfectly fine in my desktop. Kindly help me. This is what i have coded.
import java.util.*;
import java.lang.*;
import java.io.*;
import static java.lang.Math.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int testcase;
int lower_limit,upper_limit;
int i,j,k;
boolean[] a= new boolean[100001];
Arrays.fill(a, Boolean.TRUE);
Scanner sc1 = new Scanner(System.in);
testcase= sc1.nextInt();
for(;testcase>0;testcase--)
{
lower_limit= sc1.nextInt();
upper_limit= sc1.nextInt();
for(i = 2;i<sqrt(upper_limit);i++)
{
if(a[i]=true)
{
for(j=i;j<=upper_limit;j=j+i)
{
a[j]=false;
}
}
}
for(i=lower_limit;i<upper_limit;i++)
{
if(a[i]==true)
{
System.out.println(i);
}
}
}
}
}
Your array goes out of index for large values of m and n. Try this sample test case on your system where m = 999900000 and n = 1000000000. You can't store these large values as the index of the array. Even m or n = 10^8 will go out of bound index for an array.

Categories