I have been trying to figure out why I have been getting this error for almost 3 hours and I need some help to get this before my computer pays the price.
I keep getting this error
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 13
at StarsTable.checkIfStar(StarsTable.java:102)
at Stars.main(Stars.java:20)
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
public class StarsTable
{
private ArrayList<Integer> a = new ArrayList<Integer>();
private String title;
private String readLine = null;
private int rows = 0;
private Integer array[][];
public StarsTable( String fileName)
{
try
{
BufferedReader br = new
BufferedReader(new FileReader( fileName));
title = br.readLine();
while(( readLine = br.readLine()) != null)
{
System.out.println(readLine);
addArray(readLine);
rows++;
}
br.close();
}
catch(IOException e)
{
System.err.println("File Not Found. Please "
+ "enter filename in command line.");
System.exit(1);
}
}
public String title()
{
return title;
}
public void addArray(String readLine)
{
int i = 0;
String[] splitLine = readLine.split("\\s+");
for(i = 0; i < splitLine.length; i++)
{
a.add(Integer.valueOf(splitLine[i].trim()));
}
}
public Integer[][] getArray()
{
toArray();
return array;
}
public void toArray()
{
array = new Integer[rows][a.size() / rows];
int g = 0;
for (int i = 0; i < rows; i++)
{
System.out.println();
for (int k = 0; k < (a.size() / rows); k++)
{
array[i][k] = a.get(g);
System.out.print(array[i][k] + " ");
g++;
}
}
}
public int checkIfStar(int i, int k)
{
Integer check = 0;
// Top Left Corner
if (i == 0 && k == 0)
check = array[i][k] + array[i+1][k] + array[i][k+1];
// Top Right Corner
else if (i == a.size() / rows && k == 0)
check = array[i][k] + array[i-1][k] + array[i][k+1];
// Bottom Left Corner
else if (i == 0 && k == array.length)
check = array[i][k] + array[i][k-1] + array[i+1][k];
// Bottom Right Corner
else if (i == array[0].length && k == array.length)
check = array[i][k] + array[i-1][k] + array[i][k-1];
// Top Row
else if ((i != 0 && i != array[k].length) && k == 0)
check = array[i][k] + array[i-1][k] + array[i+1][k] + array[i][k+1 ];
// Bottom Row
else if ((i != 0 && i != array[k].length) && k == array.length)
check = array[i][k] + array[i-1][k] + array[i][k-1] + array[i+1][k];
// Left Side
else if(i == 0 && k != 0 && k != array.length)
{
System.out.println(i + " " + k);
This is where the error is. check = array[i][k] + array[i+1][k] + array[i][k-1] + array[i][k+1];
}
// Right Side
else if(i == array[k].length && k != 0 && k !=array.length)
check = array[i][k] + array[i-1][k] + array[i][k-1] + array[i][k+1];
else
check = array[i][k] + array[i+1][k] + array[i-1][k] + array[i][k+1] + array[i][k-1];
check = check / 5;
if (check < 5)
return 0;
else
return 1;
}
}
The type of file being read in looks like the following
Title Line
0 0 0 0 0
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
The number of lines and the number of lines per line is not known for each file and the file is read in thru the command line with a main program.
You probably want == array.length -1 rather than == array.length, since array.length is 1 more than the largest index. This might apply to a.size() too, not sure.
array.length give you the length of your array. However an array start at index 0, so the last index of your array will be array.length - 1.
Therefore your test should be :
k == array.length - 1
in your checkIfStar method
Related
I'm trying to create an optimal path to collect as many 1's as I can but after I execute my code, I still have an arrow pointing to nothing as there are no more places to go. How would I remove the arrow at the end of the code?
import java.util.Arrays;
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner s1 = new Scanner(System.in);
int n = s1.nextInt();
int m = s1.nextInt();
int mat[][] = new int[n][m];
for (int i = 0; i < mat.length; i++){
for (int j = 0; j < mat[0].length; j++){
mat[i][j] = s1.nextInt();
}
}
int path[][] = new int[n][m];
for (int i = 0; i < path.length; i++){
Arrays.fill(path[i], -1);
}
int maxCoins = util(0, 0, mat, path);
System.out.println("Max coins:" + maxCoins);
int row = 0, column = 0;
System.out.print("Path:");
while(row < mat.length && column < mat[0].length){
System.out.print("(" + (row + 1) + "," + (column + 1) + ")");
System.out.print("->");
if(row < n - 1 && column < m - 1){
int down = path[row + 1][column];
int right = path[row][column + 1];
if(down > right){
row += 1;
continue;
}
else if (right > down){
column += 1;
continue;
}
else{
row += 1;
continue;
}
}
if(row + 1 < n){
row += 1;
}
else{
column += 1;
}
}
}
private static int util(int row,int column,int mat[][], int path[][]){
if(row >= mat.length || column >= mat[0].length){
return 0;
}
if(path[row][column]!= -1){
return path[row][column];
}
int right = util(row, column + 1, mat,path);
int down = util(row + 1, column, mat,path);
path[row][column]=Math.max(right, down);
if(mat[row][column] == 1){
path[row][column] += 1;
}
return path[row][column];
}
}
My current input looks like:
5 6
0 0 0 0 1 0
0 1 0 1 0 0
0 0 0 1 0 1
0 0 1 0 0 1
1 0 0 0 1 0
And output is:
Max coins:5
Path:(1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(3,6)->(4,6)->(5,6)->
I am just trying to remove the one at the end but unsure where to insert my code:
System.out.print("->");
Cleanest way would be using a StringJoiner.
You can use it as follows
StringJoiner joiner = new StringJoiner("->");
joiner.add("a");
joiner.add("b");
System.out.println(joiner); //prints a->b - you can use toString if you want to return a joined String
You can also define a prefix and suffix for your joined String.
Or if you are familiar with Streams, there is Collectors.joining("->") available.
Three solutions that come to mind:
Add another check inside the loop, and put your sysout -> thingy after that check.
Usually code would generate some kind of list or similar data about the results and return it. It's a lot simpler to print lists, because you know the length etc.
Another common solution is to use StringBuilder and correct it before generating the output with toString()
You could just do something like this:
if (!(row == mat.length - 1 && column == mat[0].length - 1)) {
System.out.print("->");
}
Or a little cleaner:
if (arrowIsNotAtTheEnd(mat, row, column)) {
System.out.print("->");
}
// ...
private static boolean arrowIsNotAtTheEnd(int[][] mat, int row, int column) {
return !(row == mat.length - 1 && column == mat[0].length - 1);
}
For java 8 and above, the String class already has a convenient join method.
CharSequence[] path=new CharSequence[]{
"(1,1)","(2,1)","(2,2)","(2,3)","(2,4)","(3,4)","(3,5)","(3,6)","(4,6)","(5,6)"};
String output=String.join("->",path);
System.out.println(output);
//output: (1,1)->(2,1)->(2,2)->(2,3)->(2,4)->(3,4)->(3,5)->(3,6)->(4,6)->(5,6)
I have a String of a length of more than 1000 character. In this string i have to print 1st character after that every 5th character.
I tried writing a program to iterate from 0th character to last character and have a count variable.
If count is equal to 5. I am printing the character and count is initializing with 0.
private static String getMaskedToken(String token) {
if (token == null)
return null;
char[] charArray = token.toCharArray();
int length = token.length();
StringBuilder sb = new StringBuilder();
int count = 0;
for (int i = 0; i < length; i++) {
count++;
if (i == 0 || i == length - 1) {
sb.append(charArray[i]);
} else if (count == 5) {
sb.append(charArray[i]);
count=0;
} else if(count < 5 && i == length-1){
sb.append(charArray[i]);
}else {
sb.append('*');
}
}
return sb.toString();
}
Need to print last character if count is less than 5 of last
iteration.
If String of length 9, "12345678" then actual output will be like
1***5**8
If String of length 9, "123456789abcd" then actual output will be
like 1***5****a**d
String output = "";
for (int i = 0; i < str.length(); i++) {
if (i == 0) {
output += str.charAt(i);
output += "***";
output += str.charAt(4);
i = 4;
} else if ((i - 4) % 5 == 0) {
output += str.charAt(i);
} else if (i == str.length()-1) {
output += str.charAt(i);
} else {
output += "*";
}
}
System.out.println(output);
}
This will print 1***5****a**d for string "123456789abcd".
try this code:
public void printFirstAndEveryFifthCharecter(String str)
{
for (int i = 0 ; i < str.length() ; i++)
{
if ((i+1) == 1 | (i+1) % 5 == 0) {
System.out.print(str.charAt(i) + "***");
}
}
if (str.length() % 5 > 0) {
System.out.print(str.charAt(str.length() - 1));
}
}
Your code should work fine. Here's an alternative without using StringBuilder and with fewer checks.
private static String getFirstFifthLast(String str) {
String[] strArray = str.split(""); //returns an array of strings with length 1
int arrayLength = strArray.length;
String result = strArray[0]; //append the first element
//append element if it is in 5th position, append "*" otherwise
for (int i = 0; i < arrayLength; i++) {
if ((i + 1) % 5 == 0) {
result += strArray[i];
} else {
result += "*";
}
}
result += strArray[arrayLength - 1]; //append the last element
return result;
}
Try this code,
private void printEvery5thCharacter(String str) {
for (int i = 1; i < str.length() - 1; i += 5) {
System.out.print(str.charAt(i - 1) + "***");
if (i == 1) {
i = 0;
}
}
if (str.length() % 5 > 0) {
System.out.print(str.charAt(str.length() - 1));
}
}
Im trying to make a multi dimensional array that contains numbers and I need to find the number neighbors (down or right) that slope by num(variable)
example :
{7,5,3},{1,5,9}
the numbers 3,5,7 are sloped by 2 and the counter is 3 ( 3 numbers )
I need to find the longest slope which means that if there slope with 3 numbers and also after that slope with 6 numbers I need to return the 6 numbers..
I tried already for about 5 hours but im completely lost , here is my code until now :
private static int longestSlope (int [][] mat, int num , int i , int j , int count , int temp,int oldi,int oldj)
{
System.out.println("oldi " +oldi);
System.out.println("oldj " +oldj);
System.out.println("temp " +temp);
System.out.println("count "+count);
System.out.println("i "+i);
System.out.println("j "+j);
if(i < mat.length-1 && j < mat[0].length-1 )
{
if(j < mat[0].length-1 && mat[i][j] - num == mat[i][j+1] )
{
if(temp == 0)
{
oldj = j;
oldi = i;
}
if(j == mat[0].length-1)
{
return longestSlope(mat,num,i,j,count,temp+1,oldi,oldj);
}
else
{
temp = longestSlope(mat,num,i,j+1,count,temp+1,oldi,oldj);
}
}
else if(i < mat.length-1 && mat[i][j] - num == mat[i+1][j])
{
if(temp == 0)
{
oldj = j;
oldi = i;
}
temp = longestSlope(mat,num,i+1,j,count,temp+1,oldi,oldj);
}
else
temp = longestSlope(mat,num,i,j+1,count,temp,oldi,oldj);
}
else if(i < mat.length-1 && j == mat[0].length-1 && temp == 0)
{
temp = longestSlope(mat,num,i+1,0,count,0,oldi,oldj);
}
else if(temp > count)
{
count = temp;
System.out.println("nihnas "+count);
return longestSlope(mat,num,oldi,oldj+1,count,0,0,0);
}
else if(temp < count)
{
longestSlope(mat,num,oldi,oldj+1,count,0,0,0);
}
return 0;
}
With this program I want to read and compare the numbers that I'm given in a text file and print out
"buy" whenever the number goes up three consecutive time and "sell" whenever the number goes down three consecutive times.
The problem with my program is that it only reads 13 of the 15 lines of the "numbers.txt" and the buy-sell is at wrong places.
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
import java.text.DecimalFormat;
public class Practise {
public static void main(String[] args) throws IOException {
int num = 0;
int up = 0;
int down = 0;
int same = 0;
FileInputStream file = new FileInputStream("numbers.txt");
Scanner scanner = new Scanner(file);
while (scanner.hasNextDouble()) {
Double[] array = new Double[15];
for (int i = 0; i < array.length; i++) {
array[i] = scanner.nextDouble();
}
for (int a = 0; a < array.length && a + 1 < array.length - 1; a++) {
num++;
System.out.print(num + " " + (array[a]));
if (array[a] < array[a + 1]) {
up++;
} else if (array[a] > array[a + 1]) {
down++;
} else {
same++;
}
if ((up >= 3 && (down > 1 || same >= 1))) {
System.out.print(" " + "sell");
up = 0;
same = 0;
} else if ((down >= 3 && (up > 1 || same >= 1))) {
System.out.print(" " + "buy");
down = 0;
same = 0;
}
System.out.println();
}
}
}
}
The file numbers.txt:
26.375
25.500
25.125
25.000
25.250
27.125
28.250
26.000
25.500
25.000
25.125
25.250
26.375
25.500
25.500
Expected output:
1 26.375
2 25.500
3 25.125
4 25.000
5 25.250 buy
6 27.125
7 28.250
8 26.000 sell
9 25.500
10 25.000
11 25.125 buy
12 25.250
13 26.375
14 25.500 sell
15 25.500
You use a + 1 < array.length - 1, which can be transformed to a < array.length - 2. I guess you understand that the second operand in && limits your iteration to 13.
a < array.length && a < array.length - 2 = a < 15 && a < 13 = a < 13
I did some minor changes on your code for it to work; you could refactor it a lot, but I stick to your style, so you can better understand the logic.
int num = 1;
//print the 1st element
System.out.println(num + " " + array[0]);
for (int a = 1; a < array.length; a++) {
num++;
System.out.print(num + " " + (array[a]));
//plz note that we check with the before, not after
if (array[a] < array[a - 1]) {
down++;
} else if (array[a] > array[a - 1]) {
up++;
} else {
same++;
}
//changed down > to down ==
if ((up >= 3 && (down == 1 || same >= 1))) {
System.out.print(" " + "sell");
up = 0;
same = 0;
}
//changed up > to up ==
else if ((down >= 3 && (up == 1 || same >= 1))) {
System.out.print(" " + "buy");
down = 0;
same = 0;
}
System.out.println();
}
Answering to OPs comment: if you want to support more than 15 records you can keep adding to a list:
List<Double> list = new ArrayList<>();
while (scanner.hasNextDouble()) {
list.add(scanner.nextDouble());
}
//if you want to work with array
Double[] array = new Double[list.size()];
array = list.toArray(array);
Here's a working example (had to change array to list)
int num = 0, up = 0, down = 0, same = 0;
FileInputStream file = new FileInputStream("numbers.txt");
Scanner scanner = new Scanner(file);
List<Double> list = new ArrayList<>();
while (scanner.hasNextDouble()) {
list.add(scanner.nextDouble());
}
int position = 0;
while (position + 2 < list.size()) {
Double[] nums = new Double[3];
System.out.println(nums[0] = list.get(position));
System.out.println(nums[1] = list.get(position + 1));
System.out.println(nums[2] = list.get(position + 2));
if (nums[1] > nums[0] && nums[2] > nums[1]) {
System.out.println("buy");
up++;
} else if (nums[1] < nums[0] && nums[2] < nums[1]) {
System.out.println("sell");
down++;
} else {
same++;
}
position += 2;
}
System.out.println("Ups total: " + up);
System.out.println("Downs total: " + down);
System.out.println("Same total: " + same);
So I have the following problem set to me: Write a program that takes an integer command-line argument N, and uses two nested for loops to print an N-by-N board that alternates between 6 colours randomly separated by spaces. The colours are denoted by letters (like 'r' for RED, 'b' for BLUE). You are not allowed to have two of the same colour next to eachother.
So, I know I probably need arrays to get around this problem. I tried several methods that all came up wrong. The following is one of my recent attempts, but I am unsure as how to now go through the grid and correct it. What the code does is make every row randomized with no colour left or right the same, but the columns are not fixed.
Note that I am a first year CS student with no programming history. I am guessing the solution to this problem isnt too complex, however, I cant see a simple solution...
int N = StdIn.readInt();
int array1[] = new int[N];
for (int column = 0; column < N; column++) {
int x = 0;
for (int row = 0; row < N; row++) {
int c = (int) (Math.random() * 6 + 1);
while (x == c) {
c = (int) (Math.random() * 6 + 1);
array1[row] = c;
}
if (c == 1) {
System.out.print("R ");
}
if (c == 2) {
System.out.print("O ");
}
if (c == 3) {
System.out.print("Y ");
}
if (c == 4) {
System.out.print("G ");
}
if (c == 5) {
System.out.print("B ");
}
if (c == 6) {
System.out.print("I ");
}
x = c;
}
System.out.println();
}
}
this was my solution for the problem. Quite convoluted though, but the logic behind it is straightforward. Each time you assign a new colour to your 2D array, you need only check the value of the array to the top and to the left of the position where you want to assign a new colour. You can only do this after you have assigned colours to the first row of the array however so you need to create separate conditions for the first row.
public class ColourGrid {
public static void main(String[] args) {
int N = Integer.parseInt(args[0]);
char[][] clrGrid = new char[N][N];
char colours[] = {'r','b','y','w','o','g'} ;
for (int counter = 0 ; counter < N; counter++) {
for (int counter2 = 0 ; counter2 < N; counter2++) {
if (counter == 0 && counter2 == 0) {
clrGrid[counter][counter2] = colours[(int)(Math.random()* 5 + 1)] ;
}
else if (counter != 0 && counter2 == 0) {
clrGrid[counter][counter2] = colours[(int)(Math.random()* 5 + 1)] ;
while (clrGrid[counter][counter2] == clrGrid[(counter)-1][counter2]) {
clrGrid[counter][counter2] = colours[(int)(Math.random()* 5 + 1)] ;
}
}
else if (counter == 0 && counter2 != 0) {
clrGrid[counter][counter2] = colours[(int)(Math.random()* 5 + 1)] ;
while (clrGrid[counter][counter2] == clrGrid[(counter)][counter2-1]) {
clrGrid[counter][counter2] = colours[(int)(Math.random()* 5 + 1)] ;
}
}
else if (counter != 0 && counter2 != 0) {
clrGrid[counter][counter2] = colours[(int)(Math.random()* 5 + 1)] ;
while (clrGrid[counter][counter2] == clrGrid[(counter)-1][counter2] || clrGrid[counter][counter2] == clrGrid[counter][(counter2)-1]) {
clrGrid[counter][counter2] = colours[(int)(Math.random()* 5 + 1)] ;
}
}
else {
clrGrid[counter][counter2] = colours[(int)(Math.random()* 5 + 1)] ;
}
}
}
for (int counter = 0 ; counter < N; counter++) {
System.out.println("");
for (int counter2 = 0 ; counter2 < N; counter2++) {
System.out.print(clrGrid[counter][counter2] + " ");
}
}
}
}