This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 2 years ago.
When I submit my code to Leetcode, it reported runtime error as:
Runtime Error Message: Line 8: java.lang.ArrayIndexOutOfBoundsException: Index 1 out of bounds for length 1
I tested that case in my local, it works fine. I thought it maybe causeed by the platform and compiler are different. I then tried to test it on Leetcode Playground. It also worked very well.
The Leetcode problem is:https://leetcode.com/problems/string-to-integer-atoi/
I would be very appreciated if anyone could let me know what's wrong with my code.
class Solution{
public int myAtoi(String str) {
if (str == null || str.length() == 0) return 0;
char chs[] = str.toCharArray();
long base = 0;
int i = 0, sign = 1;
while (chs[i] == ' ' && i < str.length()){
i++;
}
if(i == str.length()){
return 0;
}
if (chs[i] == '-') {
i++;
sign = -1;
} else if (chs[i] == '+') {
i++;
}
while (i < str.length() && (chs[i] >= '0' && chs[i] <= '9')) {
base = base * 10 + (chs[i] - '0');
if (sign * base > Integer.MAX_VALUE) return Integer.MAX_VALUE;
if (sign * base < Integer.MIN_VALUE) return Integer.MIN_VALUE;
i++;
}
return (int)(sign * base);
}
}
If pass empty string (one space or more) to myAtoi(" ") in while statement you will go beyond the boundaries of the array:
// chs = {' '}; chs.length = 1; i = 0;
while (chs[i] == ' ') {
i++;
}
You can add an additional condition i < chs.length to while loop:
while (i < chs.length && chs[i] == ' ')
screenshot with result
Related
This question already has answers here:
Java charAt() String index out of range: 0
(5 answers)
How do I compare strings in Java?
(23 answers)
Closed 3 years ago.
Hi I keep getting this error whenever I try to input an empty String. Everything else so far works and if I put a space inside the String it works. I know this is really picky but I'm super curious what I should do in this situation to make sure it returns just an empty String.
**> HW2.nthWord(2,"")
java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.lang.String.charAt(Unknown Source)
at HW2.nthWord(HW2.java:124)**
I did create a special instance for when this value is put in but it still does not work.
What do I need to to correct this?
/*nthWord takes an int and a String as input and returns a String:
The input int represents a number n that is assumed to be positive, and the output string
contains every nth word of the input string, starting with the first word, separated by a single space.
For this method, a word is defined to be a sequence of non-space characters.
There should be no space at the end of the output string.
*/
public static String nthWord( int number, String input ){
StringBuilder create = new StringBuilder();
int totalspaces = 0; //This is to hold a count of the number of spaces in a String
if( number == 0){
return input;
}
if(input == ""){
return input;
}
else{
for(int i = 0; input.charAt(i) != ' '; i = i + 1){
create.append(input.charAt(i));
}
for( int i = 0; i < input.length() - 1 ; i = i + 1){
if(input.charAt(i) == ' ' && i < input.length() - 1 && input.charAt(i+1) != ' '){
if( i != input.length()-1 && input.charAt(i+1) != ' '){
totalspaces = totalspaces + 1;
}
if(totalspaces % number == 0 && totalspaces != 0){
create.append(' ');
for(int j = i+1; input.charAt(j) != ' ' && j < input.length(); j = j+1){
create.append(input.charAt(j));
i = j;
}
}
}
}
return create.toString();
}
}
I noticed a few things
for(int i = 0; input.charAt(i) != ' '; i = i + 1){
create.append(input.charAt(i));
}
This loops will keep adding characters of "input" until it reaches a space' ' character. If input does not have a space character then this loop will go beyond the length of input and cause the error. You may want something like:
for(int i = 0; i < input.length(); i = i + 1){
if(input.charAt(i) == ' ' ){
break;
} else {
create.append(input.charAt(i));
}
}
Also, when you get to the line:
if(input.charAt(i) == ' ' && i < input.length() - 1 && input.charAt(i+1) != ' '){
you already know that i < input.length() - 1 because you are in a for loop. You may change that line to:
if(input.charAt(i) == ' ' && input.charAt(i+1) != ' '){
For the same reason, your next section:
if( i != input.length()-1 && input.charAt(i+1) != ' '){
totalspaces = totalspaces + 1;
}
can be changed to
if( i != input.length()-1 ){
totalspaces = totalspaces + 1;
}
Also, I noticed that you may be making the problem harder than it needs to be. The problem will be much easier if you solve it in a single for-loop.
for(int i = 0; i < input.length(); i = i + 1){
if( x ) //x is some code that determines if you are part of the nth word
create.append(input.charAt(i));
}
Here's my code that I've written :
public String binary(String s)
{
String[] a = {
"0000","0001","0010","0011","0100","0101","0110","0111",
"1000","1001","1010","1011","1100","1101","1110","1111"
};
String k = "";
for(int i = 0; i <= s.length() - 1; i++)
{
if (s.charAt(i) == 'a') { k += a[10]; }
else if (s.charAt(i) == 'b') { k += a[11]; }
else if (s.charAt(i) == 'c') { k += a[12]; }
else if (s.charAt(i) == 'd') { k += a[13]; }
else if (s.charAt(i) == 'e') { k += a[14]; }
else if (s.charAt(i) == 'f') { k += a[15]; }
else { k += a[i]; }
}
return k;
}
I am getting output as a[0-9] = 0000. How can I fix this? What am I doing wrong?
The problem is with use of a[i]. It is a logical error. Because i is loop variable which indicates the current index in s String. But you are using it to indexing it in variable a. So, i variable is use incorrectly here.
Following is corrected (and a bit optimized) code. See it working here:
public class HexaDecimal
{
public String binary(String s)
{
String[] a= {"0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"};
String k="";
for(int i=0;i<s.length();i++)
{
char ch = Character.toUpperCase(s.charAt(i));
if(ch>='A' && ch <= 'F') k+= a[ch - 'A' + 10];
else k+= a[ch - '0'];
}
return k;
}
}
Replace k+=a[i]; with k+=a[s.charAt(i) - '0'];
You're using your string index loop variable as an index into a rather than the character at that location in the string.
You need to do - '0' to convert from unicode codepoint to the value it represents as an ASCII digit (which I assume you want to use here)
Your last else does the incorrect calculation. It does not take into consideration what is inputted, only the position. You want it to be
else {
k += a[s.charAt(i) - '0'];
}
There are easier ways to get the binary representation of hexadecimals, and you probably also want to check the input that it does not contain anything else than 0-9 or a-f.
You can change the for loop to this:
for(int i=0; i < s.length(); i++)
{
char c = s.charAt(i);
if (c >= '0' && c <= '9') k += a[c - '0'];
else if (c >= 'a' && c <= 'f') k += a[c - 'a' + 10];
else if (c >= 'A' && c <= 'F') k += a[c - 'A' + 10];
else throw new InvalidArgumentException(s);
}
This is a lot simpler and self-explanatory, at least in my opinion. Handles digits, uppercase and lowercase letters, and fails in an expected way on bad input.
I've wrote a method/function in Java which returns the result of a given basic equation. This equation will be given as a String and I think I got this method working but don't know why I need this one line of Code because this should work without it. After trying for more than an hour to solve it I gave up and hope you can give me an aswer.
Here the Code:
public static double format(String s) {
char[] c = s.toCharArray();
if(s.contains("(")) {
int openbrackets = 0;
for (int i = 0; i < s.length() - 2; i++) {
if (c[i] == '(') openbrackets++;
else if (c[i] == ')') {
openbrackets--;
if(openbrackets == 0) {
s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
break;
}
}
}
}
if (s.contains("(")) { // String can still contains brackets
s = "" + format(s);
}
c = s.toCharArray();
for(int i = c.length-1; i >= 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
for(int i = s.length()-1; i > 0; i--) {
if(c[i] == '*') {
return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
} else if (c[i] == '/') {
return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
}
}
return s.equals("") ? 0 : Double.parseDouble(s); // I don't understand why I need to do this line
}
Description:
I don't know why I need this s.equals("") ? : because the String never should be empty however when I run it with this equation ((23)+(23-23-432-35-1-2-4231+2312+12323-(-3))*3/2) for example I get an error without it.
I need the parser to convert config Strings into Numbers for example when it comes to screenresolution. I know I can also use Libraries but I want to try these things by myself.
PS: Dont hate me just because I don't use libraries. I really tried to figure it out and I have fun doing it. I would just like to know why I have to write this little Codeline as I don't figure it out...
Edit: Error was a NumberFormatException as the Parsing got an empty String... Got my error now also the OverflowException which was mentioned in the comments...
EDIT: To everyone who MIGHT use something like this in the future:
Here the Code which actually works:
public static double format(String s) {
s = s.replace(" ", "");
s = s.replace("\t", "");
char[] c = s.toCharArray();
if(s.contains("(")) {
int openbrackets = 0;
for (int i = 0; i < s.length(); i++) {
if (c[i] == '(') openbrackets++;
else if (c[i] == ')') {
openbrackets--;
if(openbrackets == 0) {
s = s.replace(s.substring(s.indexOf('('), i+1), ""+(format(s.substring(s.indexOf('(')+1, i))));
break;
}
}
}
}
if (s.contains("(")) s = "" + format(s);
c = s.toCharArray();
for(int i = c.length-1; i > 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
for(int i = s.length()-1; i > 0; i--) {
if(c[i] == '*') {
return format(s.substring(0, i)) * Double.parseDouble(s.substring(i+1, s.length()));
} else if (c[i] == '/') {
return format(s.substring(0, i)) / Double.parseDouble(s.substring(i+1, s.length()));
}
}
return s.equals("") ? 0 : Double.parseDouble(s);
}
I'm fairly sure this is at least one location in your code where you pass a 0 length string to your format function:
c = s.toCharArray();
for(int i = c.length-1; i >= 0; i--) {
if(c[i] == '+') {
return format(s.substring(0, i)) + format(s.substring(i+1, s.length()));
} else if(c[i] == '-') {
return format(s.substring(0, i)) - format(s.substring(i+1, s.length()));
}
}
Your loop counter in (int i = c.length-1; i >= 0; i--) will get decremented until it is 0 in value if there are no + or - values in the input string.
Then you call format(s.substring(0, i)) where i = 0 so I think this is one place where you will be passing a zero length/empty string to your function.
Please use a debugger and step through your code - not only would it teach you a valuable skill it would also probably give you the answer you're looking for.
public static int calcScore(char[] inputChars) {
int gameScore = 0;
for(int i = 0; i < inputChars.length; i++) {
System.out.println(inputChars[i]);
if(inputChars[i] == 'X') {
gameScore += 10;
gameScore += getPointsStrikeSpare(i, inputChars);
} else if (inputChars[i] == '-') {
gameScore += 0;
} else if (inputChars[i] == '/') {
gameScore += 10;
gameScore += getPointsStrikeSpare(i, inputChars);
} else {
gameScore += Character.getNumericValue(inputChars[i]);
}
}
return gameScore;
}
So my problem is that I want to itterate through the inputChars array (created using .toCharArray()) and it works fine but it cannot process the last character.
Here is the content of the input variable: "X-/X5-8/9-X811-4/X".
inputChars is input.toCharArray().
Here is the output when I run the code :
X
-
/
X
5
-
8
/
9
-
X
8
1
1
-
4
/
X
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 18
at betterCalculateScore.getPointsStrikeSpare(betterCalculateScore.java:37)
at betterCalculateScore.calcScore(betterCalculateScore.java:20)
at betterCalculateScore.main(betterCalculateScore.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
I have tried using i < inputChars.length - 1 but then it just doesn't count the last character.
Here is the content of getPointsStrikeSpare :
public static int getPointsStrikeSpare(int i, char[] inputChars) {
int points = 0;
if(inputChars[i] == 'X') {
if(inputChars[i+1] == '-') {
points += 0;
} else if (inputChars[i+1]== '/') {
points += 10;
} else {
points += Character.getNumericValue(inputChars[i+1]);
}
if(inputChars[i+2] == '-') {
points += 0;
} else if (inputChars[i+2]== '/') {
points += 10;
} else {
points += Character.getNumericValue(inputChars[i+2]);
}
} else {
if(inputChars[i+1] == '-') {
points += 0;
} else if (inputChars[i+1]== '/') {
points += 10;
} else {
points += Character.getNumericValue(inputChars[i+1]);
}
}
return points;
}
In general, if the value of 'i' is equal to or less than the length of (array_size - 1), a[i] would be valid.
However, in this method, public static int getPointsStrikeSpare(int i, char[] inputChars) one can see that a[i+1] and a[i+2] end up getting queried in different code paths in the if-else structure. So, if your 'i' index already reached the end of the array, this is going to be Out of Bounds.
Ex: X-/X5-8/9-X811-4/X
The size of this is 18. So, the legal values to refer are from 0-17 i.e., a[0] to a[17], since indexing in array starts from 0. Towards the end of the program, index counter 'i' becomes 17.
if(inputChars[i] == 'X') { // VALID
if(inputChars[i+1] == '-') { // INVALID
points += 0;
} else if (inputChars[i+1]== '/') { // INVALID
points += 10;
} else {
points += Character.getNumericValue(inputChars[i+1]); // INVALID
}
if(inputChars[i+2] == '-') { // INVALID
You get the general idea here.
At various places in the public static int getPointsStrikeSpare(int i, char[] inputChars) method, elements are being accessed which do not belong to the array length boundary. Consider the code blocks:
if(inputChars[i+1] == '-')
as well as
if(inputChars[i+2] == '-') {
In the case of i == inputChars.length - 1, both i+1 as well as i+2 exceed the array length, hence the java.lang.ArrayIndexOutOfBoundsException exception.
This question already has answers here:
Conditional statement true in both parts of if-else-if ladder
(4 answers)
Closed 2 years ago.
For those who don't know, FizzBuzz is the following problem:
Write a program that prints the numbers from 1 to 100. But for
multiples of three print "Fizz" instead of the number and for the
multiples of five print "Buzz". For numbers which are multiples of
both three and five print "FizzBuzz".
Every FizzBuzz solution I find is either some crazy esoteric solution made for the sake of being original, or your basic if-else chain:
for(int i = 1; i <= 100; i++) {
if(i % 3 == 0 && i % 5 == 0) {
System.out.println("FizzBuzz");
} else if (i % 3 == 0) {
System.out.println("Fizz");
} else if (i % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(i);
}
}
I am looking for a simple solution that aims to take out the "FizzBuzz" if statement. I have this in mind:
for(int i = 1; i <= 100; i++) {
if (i % 3 == 0)
System.out.print("Fizz");
if (i % 5 == 0)
System.out.println("Buzz")
else
System.out.println(i);
}
But this doesn't work. I assume it would be able to print FizzBuzz by entering both ifs, for Fizz and for Buzz, but if the number is, for example, 3, it would print Fizz3. How do I avoid this?
What you're trying to do is
if (a)
...
if (b)
...
else // if neigther a nor b
...
This is simply not possible. An else can only belong to a single if. You have to go with the slightly longer variant.
To avoid doing redundant evaluations of the modulo operator, you could formulate the loop body as
boolean fizz = i % 3 == 0;
boolean buzz = i % 5 == 0;
if (fizz)
System.out.print("Fizz");
if (buzz)
System.out.print("Buzz");
if (!(fizz || buzz))
System.out.print(i);
System.out.println();
Another one would be
String result = "";
if (i % 3 == 0) result = "Fizz";
if (i % 5 == 0) result += "Buzz";
if (result == "") result += i;
System.out.println(result);
Your first if statement is all alone.
So, your code hits the first statement, which is ONLY an if statement, and then goes on to the next, which is an if/else statement.
RosettaCode has a good example without using AND operators.
int i;
for (i = 0; i <= 100; i++) {
if ((i % 15) == 0)
cout << "FizzBuzz" << endl;
else if ((i % 3) == 0)
cout << "Fizz" << endl;
else if ((i % 5) == 0)
cout << "Buzz" << endl;
else
cout << i << endl;
}
If your only goal is to avoid using &&, you could use a double negation and DeMorgan's laws:
for(int i = 1; i <= 100; i++) {
if(!(i % 3 != 0 || i % 5 != 0)) {
System.out.println("FizzBuzz");
} else if (i % 3 == 0) {
System.out.println("Fizz");
} else if (i % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(i);
}
}
You can avoid && using the fact that i % 3 == 0 and i % 5 == 0 implies i % 15 == 0, as per RFC1337's answer.
Another solution is to use a switch on the remainder (mod 15, which is 5 times 3):
for(int i = 1; i <= 100; i++) {
final int mod = i % 15;
switch (mod) {
case 0:
case 3:
case 6:
case 9:
case 12:
System.out.print("Fizz");
if (mod != 0) break;
case 5:
case 10:
System.out.print("Buzz");
break;
default:
System.out.print(i);
}
System.out.println();
}
This is my solution. Granted, it's a bit convoluted (as in roundabout), but I believe it suits your requirement.
int main()
{
char fizzpass=0;
unsigned short index=0;
for(index=1;index<=100;index++)
{
if(0 == (index%3))
{
printf("Fizz");
fizzpass = 1;
}
if(0 == (index%5))
{
if(1 == fizzpass)
{
fizzpass = 0;
}
printf("Buzz\n");
continue;
}
if(1 == fizzpass)
{
fizzpass = 0;
printf("\n");
continue;
}
printf("%d\n",index);
}
return 0;
}
Regards.
Just add a flag variable and use System.out.print:
package com.stackoverflow;
public class FizzBuzz {
public static void main(String[] args) {
for (int i = 1; i <= 100; i++) {
boolean printed = false;
if (i % 3 == 0) {
printed = true;
System.out.print("Fizz");
}
if (i % 5 == 0) {
printed = true;
System.out.print("Buzz");
}
if (printed) {
System.out.println();
} else {
System.out.println(i);
}
}
}
}
This doesn't take out the if statements but does not use the && (and) operator, you could flip the binary operators.
//FizzBuzz Case
if(!(a % 3 != 0 || a % 5 != 0)){ //flips
result[index] = "FizzBuzz";
index++;
}
Don't use an if statement at all.
import java.util.*;
import java.lang.*;
import java.io.*;
class FizzBuzz
{
public static void main (String[] args) throws java.lang.Exception
{
String[] words = {"", "Fizz", "Buzz"};
String[] nwords = {"", ""};
for(int i = 1; i < 101; ++i)
{
int fp = (i % 3 == 0) ? 1 : 0;
int bp = ((i % 5 == 0) ? 1 : 0) * 2;
int np = ((fp > 0 || bp > 0) ? 1: 0);
nwords[0] = Integer.toString(i);
System.out.print(words[fp]);
System.out.print(words[bp]);
System.out.println(nwords[np]);
}
}
}
See it on ideone.
public class fizzbuzz
{
public static void main(String[] args)
{
String result;
for(int i=1; i<=100;i++)
{
result=" ";
if(i%3==0)
{
result=result+"Fizz";
}
if(i%5==0)
{
result=result+"Buzz";
}
if (result==" ")
{
result=result+i;
}
System.out.println(result);
}
}
}
This is the most efficient way I could come up with. Hope it helps! :)
Crazy albeit unrelated solution done in Python3
#!/usr/bin/python3
for i in range(1,100):
msg = "Fizz" * bool(i%3==0)
msg += "Buzz" * bool(i%5==0)
if not msg:
msg = i
print(msg)