How to fix "StringIndexOutOfBoundsException" error? - java

I need to make a program that prints the longest common sub-string out of two strings.
for example:
String str1 = "abcdef";
String str2 = "abcgef";
the longest common string should be "abc".
I can only use loops, strings, and arrays! no methods/functions etc.. I'm a beginner and although I know functions I am not allowed to use it.
I tried using a count variable so that the last letter wont be compared to others chars from the second string over and over but the same error occurs.
String com = "";
String com2 = "";
int a;
int b;
for (i = 0; i < str1.length(); i++) {
int count1 = 0;
int count2 = 0;
for (int j = 0; j < str2.length(); j++) {
a = i;
b = j;
com2 = "";
while (str1.charAt(a) == str2.charAt(b)) {
com2 = com2 + str1.charAt(a);
if (com2.length()>com.length()) {
com = com2;
}
if (a<str1.length()-1) {
a++;
}
if (b<str2.length()-1) {
b++;
}
}
}
}
System.out.println(com);
like I said, the result should be "abc" and that's it, but I get a runtime error saying StringIndexOutOfBoundsException out of range 6.
thanks!

You have your exception because of you loop till a<str1.length() and b<str2.length(). You should change it to a<str1.length()-1.
It happens because your string has length =6, but you start from 0. So the 6th element will be 5.
Also, in while{} you have endless loop when a and b reach last index of str1 and str2, so, be carefull.
P.S.
You can change it to
public void method() {
StringBuilder com = new StringBuilder();
String str1 = "abcdef";
String str2 = "abcgef";
if (str1.length() == str2.length()) {
for (int i = 0; i < str1.length() - 1; i++) {
if (str1.charAt(i) == str2.charAt(i)) {
com.append(str2.charAt(i));
continue;
} else {
break;
}
}
System.out.println(com);
} else {
System.out.println("They have different length");
}
}

as mentioned above there are some compile-errors (try to use an IDE, that helps).
After cleaning those up, I made some changes and it should work:
String str1 = "abcdef";
String str2 = "abcgef";
String com = "";
String com2 = "";
int a;
int b;
for (int i = 0; i < str1.length(); i++) {
//counts removed (never used)
for (int j = 0; j < str2.length(); j++) {
a = i;
b = j;
com2 = ""; // Reset before start a new Check Loop
while (str1.charAt(a) == str2.charAt(b)) {
com2 = com2 + str1.charAt(a);
if (com2.length() > com.length()) {
com = com2;
}
/**
* length() goes from 0 (empty String) to n
* index 0 is the first char in that String
* so you need to adjust that (the simple way is -1)
*/
if(a < str1.length()-1) {
a++;
}
if(b < str2.length()-1) {
b++;
}
//check for end of String -> Exit loop
if(a >= str1.length()-1 && b >= str2.length()-1) {
break;
}
}
}
}
System.out.println(com);
}

You get an exception because you access str1.charAt(a) after incrementing a, without checking if it is still in bounds. Same for str2.charAt(b).
Change the while loop guard to:
while (a < str1.length() && b < str2.length() && str1.charAt(a) == str2.charAt(b))

Two mistakes on your code :
You increment your while loop variables if they are lower than the associated string length. For str1 with a length of 6, if a is equal to 5, which is the last index of str1, you will have the StringIndexOutOfBoundsException (same on b / str2 )
You don't reinitialize com2 at the end of the while loop
Your code should be :
String com = "";
String com2 = "";
int a;
int b;
for (i=0; i<str1.length(); i++) {
int count1 = 0;
int count2 = 0;
for (int j=0; j<str2.length(); j++) {
a = i;
b = j;
while (str1.charAt(a) == str2.charAt(b)) {
com2 = com2 + str1.charAt(a);
if (com2.length()>com.length()) {
com = com2;
}
if (a<str1.length() - 1) {
a++;
}
if (b<str2.length() - 1) {
b++;
}
}
com2 = "";
}
}
System.out.println(com);

public class Main
{
public static void main (String[]args)
{
String com = "";
String com2 = "";
String str1 = "bowbowbowbow"; // took the liberty of initializiating
String str2 = "heloobowbowhellooo";
int a;
int b;
for (int i = 0; i < str1.length (); i++)
{
// removed redundant declaration and initializiation of count 1 and count 2
for (int j = 0; j < str2.length (); j++)
{
a = i;
b = j;
com2 = ""; // com2 should be made empty for each iteration
while ( ( str1.charAt (a) == str2.charAt (b) ) && (a < str1.length() - 1 ) && ( b < str2.length() -1) )
{
com2 = com2 + str1.charAt (a);
if (com2.length () > com.length ())
{
com = com2;
}
a++;
b++;
}
}
}
System.out.println (com);
}
}
Made some changes and have commented about it in the code. Seems to be working fine

you look something like this.
String str1="abcdef";
String str2="abcgefghj";
String com = "";
int min =Math.min(str1.length(), str2.length());
for (int i =0; i< min ; i++)
{
if(str1.charAt(i) == str2.charAt(i))
{
com = com + str1.charAt(i);
}
else {
break;
}
}
System.out.println(com);

Related

Add Two Polynomials Java Program

I am working on this simple program that adds two polynomials. However, I am getting wrong results and could not spot the mistake.
import java.util.LinkedList;
public class Polynomial {
private LinkedList<Term> terms = new LinkedList<Term>();
private class Term {
private int coef;
private int exp;
public Term(int coef, int exp) {
this.coef = coef;
this.exp = exp;
}
public int getCoef() {
return coef;
}
public int getExp() {
return exp;
}
public String toString() {
return (this.coef + "x^" + this.exp);
}
}
public String addPoly(String first, String second) {
LinkedList<Term> otherTerms = new LinkedList<Term>();
String result = "";
String [] termsArray1 = first.split(";");
String [] termsArray2 = second.split(";");
for (int i = 0; i < termsArray1.length; i++) {
String [] temp = termsArray1[i].split("x\\^");
int currentCoef = Integer.parseInt(temp[0]);
int currentExp = Integer.parseInt(temp[1]);
Term currentTerm = new Term(currentCoef, currentExp);
terms.add(currentTerm);
}
for (int i = 0; i < termsArray2.length; i++) {
String [] temp = termsArray2[i].split("x\\^");
int currentCoef = Integer.parseInt(temp[0]);
int currentExp = Integer.parseInt(temp[1]);
Term currentTerm = new Term(currentCoef, currentExp);
otherTerms.add(currentTerm);
}
int i = 0;
int j = 0;
while (true){
if(i == terms.size() || j == otherTerms.size()) {
break;
}
if(terms.get(i).getExp() < otherTerms.get(j).getExp()) {
result += (otherTerms.get(j).toString() + ";");
j++;
}
if(terms.get(i).getExp() > otherTerms.get(j).getExp()) {
result += (terms.get(i).toString() + ";");
i++;
}
if(terms.get(i).getExp() == otherTerms.get(j).getExp()) {
Term temp = new Term((terms.get(i).getCoef() + otherTerms.get(j).getCoef()), terms.get(i).getExp());
result += (temp.toString() + ";");
i++;
j++;
}
}
result = result.substring(0, result.length()-1);
return result;
}
}
::Test::
String s3 = "5x^2;-4x^1;3x^0";
String s4 = "6x^4;-1x^3;3x^2";
Polynomial p = new Polynomial();
System.out.println(p.addPoly(s4, s3));
Expected result: 6x^4;-1x^3;7x^2;-4x^1;3x^0
Actual result: 3x^4;7x^2;-1x^1;10x^0
The problem is that when your loop exits, one of the following can still be true:
i < terms.size()
j < j == otherTerms.size()
And this is the case with your example input. This means that part of one of the terms has not been processed and integrated into the output.
A second problem is that your multiple if statements are not exclusive; after the first if block is executed and j++ has executed, it might well be that j is an invalid index in otherTerms when the second if is evaluated. This should be avoided by turning the second and third if into else if.
Here is a fix for that loop:
while (i < terms.size() || j < otherTerms.size()) {
if(i == terms.size() || j < otherTerms.size() && terms.get(i).getExp() < otherTerms.get(j).getExp()) {
result += (otherTerms.get(j).toString() + ";");
j++;
}
else if(j == otherTerms.size() || i < terms.size() && terms.get(i).getExp() > otherTerms.get(j).getExp()) {
result += (terms.get(i).toString() + ";");
i++;
}
else if(terms.get(i).getExp() == otherTerms.get(j).getExp()) {
Term temp = new Term((terms.get(i).getCoef() + otherTerms.get(j).getCoef()), terms.get(i).getExp());
result += (temp.toString() + ";");
i++;
j++;
}
}
Better approach
Your approach is not really OOP. Ideally, the first expression should serve to create one instance of Polynomial and the other expression should serve to create another instance of Polynomial. Then there should be a method that can add another Polynomial instance to the own instance. Finally there should be a toString method that returns the instance as a string in the required format. Your driver code would then look like this:
Polynomial a = new Polynomial("5x^2;-4x^1;3x^0");
Polynomial b = new Polynomial("6x^4;-1x^3;3x^2");
Polynomial sum = a.addPoly(b);
System.out.println(sum.toString());
This is much more object oriented, and will automatically avoid the code repetition that you currently have.

How can I compare these two strings and remove a common letter without using arrays?

This was the code I designed to solve this problem but it seems not to work at all.I used nested for loops to compare the letters of the first string and the second string since they are likely to have different lengths
import java.util.*;
public class Trim
{
public static String myTrim(String input, String list)
{
String r = "";
for (int i = 1; i < input.length();i++)
{
for (int k = 1; k < list.length();k++)
{
if (input.charAt(i) != list.charAt(i))
{
r += input.charAt(i);
}
}
}
return r;
}
}
I guess you should use the method String.indexOf.
So:
public static String myTrim(String input, String list)
{
StringBuilder result = new StringBuilder();
char c;
for (int i = 0; i < input.length(); i++)
{
c = input.charAt(i);
if (list.indexOf(c) < 0)
result.append(c);
}
return result.toString();
}
Try using a flag to determine whether to character gets repeated or not:
String r = "";
for (int i = input.length() - 1; 0 <= i; i --) {
if (-1 == list.indexOf(input.charAt(i))) {
r += input.charAt(i);
}
}
OR
String r = "";
boolean found;
for (int i = input.length() - 1, j = list.length() - 1; 0 <= i; i--) {
found = false;
for (int k = j; 0 <= k; k--) {
if (list.charAt(k) == input.charAt(i)) {
found = true;
break;
}
}
if (!found) {
r += input.charAt(i);
}
}
We have to filter out the characters from input which appears in list.
Now we have to check whether each character of the input appears in the list or not.
The k value will be less then list.length() if the character of input present in the list string.
After the loop we check the k value and append it to the new string.
public static String myTrim(String input, String list)
{
String r = "";
for (int i = 0; i < input.length();i++)
{
int k = 0;
for (; k < list.length();k++)
{
if (input.charAt(i) == list.charAt(k))
{
break;
}
}
if(k == list.length())
r += input.charAt(i);
}
return r;
}
A nice one-liner solution would be to use Guava Charmatcher:
CharMatcher.anyOf(list).removeFrom(input);
I have tried this code and it's working fine with both of your inputs
for (int i = 0; i < S1.length(); i++) {
for(int j=0;j< S2.length();j++) {
if(S1.charAt(i)==S2.charAt(j)) {
char Temp= S2.charAt(j);
String Temp2=String.valueOf(Temp);
S1=S1.replace(Temp2, "");
}
}
}
This is code
import java.util.Scanner;
public class StringRemoveChar {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String S1, S2;
S1 = scanner.nextLine();
S2 = scanner.nextLine();
for (int i = 0; i < S1.length(); i++) {
for (int j = 0; j < S2.length(); j++) {
if (S1.charAt(i) == S2.charAt(j)) {
char Temp = S2.charAt(j);
String Temp2 = String.valueOf(Temp);
S1 = S1.replace(Temp2, "");
System.out.println(S1.length());
}
}
}
System.out.println(S1);
}
}
Input:
Miyazaki
you
Output:
Miazaki
We can use replaceAll and use one loop over ,this will make the solution simple
public static String myTrim(String input, String list)
{
for(int i=0;i<list.length();i++)
{
input=input.replaceAll(list.charAt(i)+"","");
}
return input;
}
Input: myTrim("Miyazaki","you")
Output: Miazaki
Full code for reference
package stackoverflow.string;
public class StringManipulation
{
public static void main(String[] args)
{
System.out.println(myTrim("University of Miami","city"));
}
public static String myTrim(String input, String list)
{
for(int i=0;i<list.length();i++)
{
input=input.replaceAll(list.charAt(i)+"","");
}
return input;
}
}

find subsequence in a string: Java

I have a string hackkkerrank and i have to find if any subsequence gives a result as hackerrank, if it is present then it gives result as YES otherwise NO.
Sample:
hereiamstackerrank: YES
hackerworld: NO
I don't know which String method should be applied, can anyone help me how to do it?
Here is my code:
static String hackerrankInString(String s) {
char str[] = {
'h','a','c','k','e','r','a','n','k'
};
while (s.length() >= 10) {
for (int i = 0; i < s.length(); i++) {
for (char c: str) {
if (s.indexOf(c)) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
}
}
Here is a built-in way, using regex:
String regex = "[^h]*+h[^a]*+a[^c]*+c[^k]*+k[^e]*+e[^r]*+r[^r]*+r[^a]*+a[^n]*+n[^k]*+k.*";
System.out.println("hereiamstackerrank".matches(regex) ? "YES" : "NO");
System.out.println("hackerworld".matches(regex) ? "YES" : "NO");
Output
YES
NO
You can make a generic method to check for subsequence like this:
public static boolean containsSubsequence(String subsequence, String text) {
StringBuilder buf = new StringBuilder();
for (int i = 0, j; i < subsequence.length(); i = j) {
j = subsequence.offsetByCodePoints(i, 1);
String ch = Pattern.quote(subsequence.substring(i, j));
buf.append("[^").append(ch).append("]*+").append(ch);
}
String regex = buf.append(".*").toString();
return text.matches(regex);
}
Test
System.out.println(containsSubsequence("hackerrank", "hereiamstackerrank") ? "YES" : "NO");
System.out.println(containsSubsequence("hackerrank", "hackerworld") ? "YES" : "NO");
Output
YES
NO
Of course, it is not very efficient, but it is one way to do it.
For a simpler and more efficient solution, that doesn't handle characters in the Supplement­ary Planes, you'd do this:
public static boolean containsSubsequence(String subsequence, String text) {
int j = 0;
for (int i = 0; i < text.length() && j < subsequence.length(); i++)
if (text.charAt(i) == subsequence.charAt(j))
j++;
return (j == subsequence.length());
}
Here is an old fashioned looping way, which increments the starting position of the second string based upon where the last char was found
String str1 = "hackerrank";
String str2 = "hereiamstackerrank";
int index = 0;
for (int i = 0; i < str1.length(); i++)
{
boolean notfound = true;
int x = index;
for (; x < str2.length(); x++) {
if (str1.charAt(i) == str2.charAt(x)) {
notfound = false;
break;
}
}
if (notfound) {
System.out.println("NO");
return;
}
index = x + 1;
}
System.out.println("YES");
An in-efficient alternative is
for (int i = 0; str1.length() > 0 && i < str2.length(); i++)
{
if (str1.charAt(0) == str2.charAt(i)) {
str1 = str1.substring(1);
}
}
System.out.println(str1.length() == 0 ? "YES" : "NO");
static String re="";
static String hackerrankInString(String s) {
String pattern="[^h]*+h[^a]*+a[^c]*+c[^k]*+k[^e]*+e[^r]*+r[^r]*+r[^a]*+a[^n]*+n[^k]*+k.*";
if(s.matches(pattern)){
re="YES";
}else{
re="NO";
}
return re;
}
There's no built in function in core libraries to check subsequence. There's one for substring but none for subsequence you're looking for.
You'll have to code it yourself.
Below is the pseudo code for this:
1. Traverse both original string and string under test.
2. Increment both's counter if characters are equal
3. Else increment originalString's counter only.
4. Repeat 2-3 `while` both strings are `not` empty.
5. Given string under test is subsequence if its counter is exhausted.

String compression algorithm in Java

I am looking to implement a method to perform basic string compression in the form of:
aabcccccaaa -> a2b1c5a3
I have this program:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
System.out.println(compress(str));
}
public static String compress(String str) {
char[] chars = str.toCharArray();
int count = 0;
String result = "";
for (int i = 0; i < chars.length; i++) {
char curr = chars[i];
result += curr;
for (int j = i; j < chars.length; j++) {
if (chars[j] == curr) {
count++;
}
else {
i += count;
break;
}
}
result += count;
count = 0;
}
return result;
}
}
But in my tests I am always missing the last character count.
I assume this is because the program gets out of the inner for loop before it should, but why is this the case?
Thanks a lot
You don't need two for loops for this and can do it in one go like so
String str = "aaabbbbccccca";
char[] chars = str.toCharArray();
char currentChar = str.length() > 0 ? chars[0] : ' ';
char prevChar = ' ';
int count = 1;
StringBuilder finalString = new StringBuilder();
if(str.length() > 0)
for(int i = 1; i < chars.length; i++)
{
if(currentChar == chars[i])
{
count++;
}else{
finalString.append(currentChar + "" + count);
prevChar = currentChar;
currentChar = chars[i];
count = 1;
}
}
if(str.length() > 0 && prevChar != currentChar)
finalString.append(currentChar + "" + count);
System.out.println(finalString.toString());
Output is: a3b4c5a1 for aaabbbbccccca
Keep a track of character that you are reading and compare it with next character of the string. If it is different, reset the count.
public static void stringCompression (String compression) {
String finalCompressedString = "";
char current = '1';
int count = 0;
compression = compression + '1';
for (int i = 0; i < compression.length(); i++) {
if (compression.charAt(i) == current) {
count = count + 1;
} else {
if (current != '1')
finalCompressedString = finalCompressedString + (current + Integer.toString(count));
count = 1;
current = compression.charAt(i);
}
}
System.out.println(finalCompressedString);
}
My answer for String Compression in java.
In this what i have done is and what you should have done is that , Keep a record of the characters that that are coming for a specific number of times, do so by comparing the current character with the next character , and when the current and the next character become unequal reset the value of count and repeat the whole process again for the next different character.
Hope it helps!
import java.util.*;
public class Main {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
String str = sc.nextLine();
int count = 0;
for (int i=0; i<str.length(); ++i) {
int j=i+1;
count=1;
while (j!=str.length() && str.charAt(i) == str.charAt(j)) {
count += 1;
j += 1;
i += 1;
}
System.out.print(str.charAt(i));
if (count > 1) {
System.out.print(count);
}
}
}
}

How to fill the null array with a specific number in Java ?

I'm trying to solve a palindrome problem that the input consists of Strings , if the concatenation of two strings represent a palindrome word(A palindrome is a word which can be read the same way in either direction. For example, the following
words are palindromes: civic, radar, rotor, and madam)
then save it into array to print it latter otherwise print "0"
but I'm having a problem in filling the null index with zeros , here I get Exception
for (int re = 0; re < result.length; re++) {
if (result[re].equals(null)) {
result[re] = "0";
}
}
"Exception in thread "main" java.lang.NullPointerException"
here is my full code
import java.util.Scanner;
public class Palindrome {
public static String reverse(String R2) {
String Reverse = "";
String word_two = R2;
int ln = word_two.length();
for (int i = ln - 1; i >= 0; i--) {
Reverse = Reverse + word_two.charAt(i);
}
return Reverse;
}
public static void main(String[] args) {
Scanner inpoot = new Scanner(System.in);
int stop = 0;
String pal1;
int Case = inpoot.nextInt();
String result[] = new String[Case];
String Final;
int NumberofWords;
for (int i = 0; i < Case; i++) {
NumberofWords = inpoot.nextInt();
String words[] = new String[NumberofWords];
for (int array = 0; array < words.length; array++) {
words[array] = inpoot.next();
}
for (int word1 = 0; word1 < NumberofWords; word1++) {
if (stop > Case) {
break;
}
for (int word2 = 0; word2 < NumberofWords; word2++) {
if (word1 == word2) {
continue;
}
Final = "" + words[word1].charAt(0);
if (words[word2].endsWith(Final)) {
pal1 = words[word1].concat(words[word2]);
} else {
continue;
}
if (pal1.equals(reverse(pal1))) {
result[i] = pal1;
stop++;
break;
} else {
pal1 = "";
}
}
}
}
// HERE IS THE PROBLEM
for (int re = 0; re < result.length; re++) {
if (result[re].equals(null)) {
result[re] = "0";
}
}
for (int x = 0; x < result.length; x++) {
System.out.println("" + result[x]);
}
}
}
A test such as anObject.equals(null) makes no sense. Indeed, if anObject is null, it will throw a NullPointerException (NPE), and if it is not, it will always return false.
To test if a reference is null, just use anObject == null.
If you want to check whether result[re] is null, you cannot use equals. Use the identity comparison:
if (result[re] == null) {
result[re] = "0";
}

Categories

Resources