I have wrote a below code to find a keyword co_e in the below string, where _ represents any other character.
It works good if I change the String to "aaacodebbb" or "codexxcode"
but if I change it to "xxcozeyycop" it throws StringIndexOutOfBoundsException
public int countCode(String str) {
int count = 0;
String result = "";
boolean yes = true;
for (int i = 0; i < str.length(); i++) {
// yes = str.charAt(i+3);
if (str.length() >= 3) {
if (str.charAt(i) == 'c' && str.charAt(i + 1) == 'o' && str.charAt(i + 3) == 'e')
count++;
}
}
return (count);
}
Your out-of-bounds error occured in this line:
if (str.charAt(i) == 'c' && str.charAt(i + 1) == 'o' && str.charAt(i + 3) == 'e')
The error happened at str.charAt(8) for str = "xxcozeyycop", because str.length() is 11, and str.charAt(11) is clearly out of bounds (and so are all str.charAt(str.length()))
Here is one possible solution. Note that if str.length() < 4, the for loop cannot run, as i + 3 will always go out of bounds. Also, when i == str.length() - 4 for all strings longer than four chars, i+3 would equal the last index of the string, str.length() - 1.
for (int i = 0; i < str.length() - 3; i++) {
char c1 = str.charAt(i);
char c2 = str.charAt(i + 1);
char c4 = str.charAt(i + 3);
if (c1 == 'c' && c2 == 'o' && c4 == 'e')
count++;
}
In the loop, you are checking accessing i+3. So, you have to stop when i is at 4th last position.
Replace if(str.length()>= 3) with if(str.length()>= 3 && str.length() - i >3)
OR
You can put the following as the first condition in your for loop:
if(str.length() - i <=3){
break;
}
Related
I have to write a program that takes a String as user input and then prints a substring that starts with the first vowel of the String and ends with the last. So for instance if my String is : "Hi I have a dog named Patch", the printed substring would be : "i I have a dog named Pa"
This is the code I have now:
import java.util.Scanner;
import java.util.*;
public class SousChaineVoyelle {
private static Scanner sc;
public static void main (String[] args) {
sc = new Scanner(System.in);
System.out.print("Enter a String: ");
String str = sc.nextLine();
int pos1 = 0;
int pos2 = 0;
int i;
int j;
boolean isVowel1 = false;
boolean isVowel2 = false;
for (i = 0; i < str.length(); i++){
if (str.charAt(i) == 'A' || str.charAt(i) == 'a' ||
chaine.charAt(i) == 'E' || str.charAt(i) == 'e' ||
str.charAt(i) == 'I' || str.charAt(i) == 'i' ||
str.charAt(i) == 'O' || str.charAt(i) == 'o' ||
str.charAt(i) == 'U' || str.charAt(i) == 'u' ||
str.charAt(i) == 'Y' || str.charAt(i) == 'y'){
isVowel1 = true;
break;
}
}
if (isVowel1){
pos1 = str.charAt(i);
}
for (j = str.length() - 1; j > i; j--){
if (str.charAt(j) == 'A' || str.charAt(j) == 'a' ||
str.charAt(j) == 'E' || str.charAt(j) == 'e' ||
str.charAt(j) == 'I' || str.charAt(j) == 'i' ||
str.charAt(j) == 'O' || str.charAt(j) == 'o' ||
str.charAt(j) == 'U' || str.charAt(j) == 'u' ||
str.charAt(j) == 'Y' || str.charAt(j) == 'y'){
isVowel2 = true;
break;
}
}
if (isVowel2){
pos2 = str.charAt(j);
}
String sub = chaine.substring(pos1, pos2);
System.out.print(The substring from the first vowel to the last is "\"" + sub +"\"");
}
}
this got me this:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: Index 22 out of bounds for length 22
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:55)
at java.base/jdk.internal.util.Preconditions$1.apply(Preconditions.java:52)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:213)
at java.base/jdk.internal.util.Preconditions$4.apply(Preconditions.java:210)
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:98)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:106)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:302)
at java.base/java.lang.String.checkIndex(String.java:4557)
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:46)
at java.base/java.lang.String.charAt(String.java:1515)
at SousChaineVoyelle.main(SousChaineVoyelle.java:33)
One way of looking at it is you have a lot of code to do a simple thing, which means more chances for bugs and errors.
Here's a "less code" solution:
str = str.replaceAll("(?i)^[^aeiou]*|[^aeiou]*$", "");
See live demo.
This works by matching all leading and trailing non-vowels (if any) and replacing them with nothing, effectively deleting them.
(?i) makes the match case insensitive.
After the first for loop, i will be str.length() no matter what. You may want to create another variable to hold I when it's found to remedy this.
I have been trying to figure out how to detect where and what error occurred in a regular infix expression. The first thing that I came up with looks like this...
String expression = "(12 * 12) + (12 * 9)";
int numOfDigits = 0;
int numOfOperators = 0;
boolean onDigit = false;
for (int i = 0; i < expression.length(); i++) {
char ch = expression.charAt(i);
if (Character.isDigit(ch) && !onDigit) {
numOfDigits += 1;
onDigit = true;
} else if (ch == '+' || ch == '-' || ch == '/' || ch == '*') {
numOfOperators += 1;
onDigit = false;
} else if (Character.isWhitespace(ch)) {
onDigit = false;
}
}
if (numOfDigits - 1 != numOfOperators) {
System.out.println("Missing operand(s) or operator(s) in expression");
}
The only issue with this is that I can't detect where in the expression the error is coming from. At this point, I decided to go with something that looks like this as it can detect where in the string the error is coming from. The only problem that I am having with it is that if there is an operator at the end of the string I can't figure out how to allow the program to detect that and display an error. Any help would be greatly appreciated.
for (int i = 0; i < expression.length(); i++) {
char ch = expression.charAt(i);
if (lastType.equalsIgnoreCase("") && (ch == '+' || ch == '-' || ch == '/' || ch == '*')) {
System.out.printf("Missing operand at: %d\n", lastLocation + 1);
break;
}
if (Character.isDigit(ch)) {
if (!onDigit) {
if (lastType.equalsIgnoreCase("digit")) {
System.out.printf("Missing operator at: %d\n", lastLocation + lenOfDigit);
break;
}
lastType = "Digit";
lastLocation = i + 1;
numOfDigits += 1;
onDigit = true;
}
lenOfDigit++;
} else if (ch == '+' || ch == '-' || ch == '/' || ch == '*') {
if (lastType.equalsIgnoreCase("operator")) {
System.out.printf("Missing operand at: %d\n", lastLocation + 1);
break;
}
lastType = "Operator";
lastLocation = i + 1;
numOfOperators += 1;
onDigit = false;
lenOfDigit = 0;
} else if (Character.isWhitespace(ch)) {
onDigit = false;
}
}
You can traverse the string backwards and find the first index where Character.isDigit() is true. Then simultaneously find the first index where the character is an operator. If the index for the operator is larger than the index for the digit, then you've found the discrepancy where an operator is the last character in the expression.
EDIT:
I'm assuming you want to detect when an expression has an operator that is not followed by any digit.
Eg: "(12 * 12) + (12 * 9) +"
You could detect this with:
int lastDigitIndex = -1;
int lastOperatorIndex = -1;
for (int i = expression.length()-1; i >= 0; --i)
{
char ch = expression.charAt(i);
if (Character.isDigit(ch) && lastDigitIndex == -1)
lastDigitIndex = i;
else if((ch == '+' || ch == '-' || ch == '/' || ch == '*') && lastOperatorIndex == -1)
lastOperatorIndex = i;
if (lastDigitIndex != -1 && lastOperatorIndex != -1)
break;
}
if (lastOperatorIndex > lastDigitIndex)
{
//Error found
}
How can I add 0 in front of every single digit number? I mean 1 to 01 etc.
I have tried to add ifs like
if(c >='A' && c<= 'I')
str = "0"+str;
but it just adds 0 in front of everything like abcd converts to 00001234 not 01020304.
This is my code.
String A[] = new String[size];
for (int i = 0; i < size; i++) {
A[i] = jList1.getModel().getElementAt(i);
String[] Text = A[i].split("");
String s = jList1.getModel().getElementAt(i);
String str = ("");
for (int z = 0; z < Text.length; z++) {
for (int y = 0; y < Text[z].length(); y = y + 1) {
char c = s.charAt(z);
if (c >= 'A' && c <= 'Z') {
str += c - 'A' + 1;
} else if (c >= 'a' && c <= 'z') {
str += c - 'a' + 1;
} else {
str += c;
}
}
str = str + "";
}
}
This Worked for me
public String addZero(int number)
{
return number<=9?"0"+number:String.valueOf(number);
}``
One way to do this would be to use a StringJoiner with Java 8:
String s = "abcdABCD";
s = s.chars()
.mapToObj(i -> Integer.toString((i >= 'a' && i <= 'z' ? i - 'a' : i - 'A') + 1))
.collect(Collectors.joining("0", "0", "")));
System.out.println(s);
>> 0102030401020304
String str = "abcd-zzz-AAA";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < str.length(); i++) {
char ch = str.toLowerCase().charAt(i);
if (ch >= 'a' && ch <= 'z') {
sb.append('0');
sb.append(ch - 'a' + 1);
} else {
sb.append(ch);
}
}
Result: abcd-zzz-AAA -> 01020304-026026026-010101
Final fix :-)
use String#chars to get a stream of its characters, then for each one do the manipulation you want.
public class Example {
public static void main(String[] args) {
String s = "aBcd1xYz";
s.chars().forEach(c -> {
if (c >= 'a' && c <= 'z')
System.out.print("0" + (c - 'a' + 1));
else if (c >= 'A' && c <= 'Z')
System.out.print("0" + (c - 'A' + 1));
else
System.out.print(c);
});
}
}
Ouput:
0102030449024025026
You can add zero in front of single digit number using String.format.
System.out.println(String.format("%02d",1));
System.out.println(String.format("%02d",999));
The first line will print 01, second line prints 999 no zero padding on the left.
Padding zero with length of 2 and d represents integer.
I hope this helps.
I am trying to convert string into integers but when I try to print the result I cannnot get the right output.
package com.company;
public class Main {
public static void main(String[] args){
String str ="-123456";
int i = atoi(str);
System.out.println(i);
}
public static int atoi(String str){
if (str == null || str.length() < 1)
return 0;
str = str.trim();
char flag = '+';
int i = 0;
if (str.charAt(0) == '-'){
flag = '-';
i++;
} else if (str.charAt(0) == '+'){
i++;
}
double result = 0;
while (str.length() > 1 && str.charAt(i) >= '0' && str.charAt(i) <= '9'){
result = result * 10 + (str.charAt(i)-'0');
i++;
}
if (flag == '-'){
result = -result;
}
if (result > Integer.MAX_VALUE){
return Integer.MAX_VALUE;
}
if (result < Integer.MIN_VALUE){
return Integer.MIN_VALUE;
}
return (int) result;
}
}
This is the result after I run the code
Change to this: Note i < str.length() instead of str.length() > 1
Explanation: Your error was "index out of range" meaning you're trying to access a character that isn't in the range of the length of the straight and ins this case str.charAt(7), which doesn't exist, so you have to limit i to being less than length of the string.
while (i < str.length() && str.charAt(i) >= '0' && str.charAt(i) <= '9'){
result = result * 10 + (str.charAt(i)-'0');
i++;
}
This lab for my intro class requires us to return any user input in pig latin.
The error I seem to keep getting when I run it and type any string into the console is this:
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
The error is found here:
thisWord = x.substring(indexOfCurrentNonLetter +1, indexOfNextNonLetter);
I understand from another post this is the problem:
IndexOutOfBoundsException -- if the beginIndex is negative, or endIndex is >larger than the length of this String object, or beginIndex is larger than >endIndex.
Actually, your right edge of your substring function may be lower than the left >one. For example, when i=(size-1) and j=size, you are going to compute >substring(size-1, 1). This is the cause of you error. (Answer By Bes0ul)
My question is, what is the solution to this problem?
Here are the methods I am using:
public String pigLatin(String x)
{
String thisWord = "";
x += " ";
int indexOfNextNonLetter = 0, indexOfCurrentNonLetter = 0;
for(int i = 0; i < x.length(); i++)
{
System.out.println("At least the loop works"); //Let's play a game called find the issue
if(x.charAt(i) < 65 || x.charAt(i) > 90 && x.charAt(i) < 97 || x.charAt(i) > 122) //if it isn't a letter
{
phrase += x.charAt(i); // add our non character to the new string
for(int j = 0; j < x.substring(i).length(); j++) // find the next character that isn't a letter
{
if(x.charAt(i) < 65 || x.charAt(i) > 90 && x.charAt(i) < 97 || x.charAt(i) > 122)
{
indexOfNextNonLetter = j + i;
if(j+i > x.length())
System.out.print("Problem Here");
indexOfCurrentNonLetter = i;
System.out.println("noncharacter detected"); //I hope you found the issue
j = x.length();
thisWord = x.substring(indexOfCurrentNonLetter +1, indexOfNextNonLetter);//between every pair of nonletters exists a word
}
}
phrase += latinWord(thisWord); // translate the word
i = indexOfNextNonLetter - 1;
}
}
return phrase;
}
/*
* This converts the passed word to pig latin
*/
public String latinWord(String word)
{
String lWord = "";
String beforeVowel = "";
String afterVowel = "";
boolean caps = false;
char first = word.charAt(0);
if(first > 'A' && first < 'Z')
{
first = Character.toLowerCase(first); //If the first char is capital, we need to account for this
caps = true;
}
if(containsNoVowels(word))
lWord = Character.toUpperCase(first) + word.substring(1) + "ay"; //If we have no vowels
if(word.charAt(0) == 'A' || word.charAt(0) == 'a' || word.charAt(0) == 'E' || word.charAt(0) == 'e' || word.charAt(0) == 'I' || word.charAt(0) == '0'
|| word.charAt(0) == 'O' || word.charAt(0) == 'O' || word.charAt(0) == 'o' || word.charAt(0) == 'U' || word.charAt(0) == 'u')
{
lWord = Character.toUpperCase(first) + word.substring(1) + "yay"; //If the first char is a vowel
}
if(word.charAt(0) != 'A' || word.charAt(0) != 'a' || word.charAt(0) != 'E' || word.charAt(0) != 'e' || word.charAt(0) != 'I' || word.charAt(0) != '0'
|| word.charAt(0) != 'O' || word.charAt(0) != 'O' || word.charAt(0) != 'o' || word.charAt(0) != 'U' || word.charAt(0) != 'u')
{ //If the first letter isnt a vowel but we do have a vowel in the word
for(int m = 0; m < word.length(); m++)//if we have a vowel in the word but it doesn't start with a vowel
{
if(word.charAt(m) == 'A' || word.charAt(m) == 'a' || word.charAt(m) == 'E' || word.charAt(m) == 'e' || word.charAt(m) == 'I' || word.charAt(m) == 'm'
|| word.charAt(m) == 'O' || word.charAt(m) == 'O' || word.charAt(m) == 'o' || word.charAt(m) == 'U' || word.charAt(m) == 'u')
{
for(int l = 0; l < word.substring(m).length(); l++)
{
afterVowel += word.substring(m).charAt(l); //Build the part after the first vowel
}
m += word.length();
}
else
beforeVowel += word.charAt(m);
}
if(caps == false)
lWord = afterVowel + beforeVowel + "ay";
else
{
first = Character.toUpperCase(afterVowel.charAt(0));
}
}
return lWord;
}
/*
* This function checks the string letter by letter to see if any of the letters are vowels.If there are none it returns true
*/
public boolean containsNoVowels(String wrd)
{
for(int h = 0; h < wrd.length(); h++)
{
if(wrd.charAt(h) == 'A' || wrd.charAt(h) == 'a' || wrd.charAt(h) == 'E' || wrd.charAt(h) == 'e' || wrd.charAt(h) == 'I' || wrd.charAt(h) == 'h'
|| wrd.charAt(h) == 'O' || wrd.charAt(h) == 'O' || wrd.charAt(h) == 'o' || wrd.charAt(h) == 'U' || wrd.charAt(h) == 'u')
return false;
else
return true;
}
return false;
}
I think the error lies inside your second for loop within pigLatin():
for (int j = 0; j < x.substring(i).length(); j++) // find the next character that isn't a letter
{
if(x.charAt(i) < 65 || x.charAt(i) > 90 && x.charAt(i) < 97 || x.charAt(i) > 122)
The last line shown above starts checking at char i. This is the same char you just checked in the outer loop. So the test will succeed. And I think the logic breaks down either in this iteration or a subsequent one.
I think what you want is:
for(int j = 1; j < x.substring(i).length(); j++)
{
if (x.charAt(j) < 65 || x.charAt(j) > 90 && x.charAt(j) < 97 || x.charAt(j) > 122)
Note, there are two changes:
Initialise j at 1 to test the next character in the for statement
Test the jth character, not the ith in the if statement