Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 7
at java.lang.String.charAt(Unknown Source)
at DNAmatch.findFirstMatchingPosition(DNAmatch.java:100)
at DNAmatch.run(DNAmatch.java:82)
at acm.program.Program.runHook(Program.java:1568)
at acm.program.Program.startRun(Program.java:1557)
at acm.program.Program.start(Program.java:808)
at acm.program.Program.start(Program.java:1279)
at acm.program.Program.main(Program.java:1360)
I got this weird error and I don't know what is causing it. I googled for a solution to my problem but nothing helped me solve it.
If you try as inputs for chain1 atcg and for chain2 tagaagtc, it works fine
but for inputs chain1 atcg and chain2 tagaagct then i got this error.
If anyone could help i'd appreciate it.
=================================================
import acm.program.*;
public class DNAmatch extends Program
{
public void run()
{
//The chains must only contain the characters A,T,C or G so we check the string for any irregularities.
String current, chain2; Boolean flag=true; int errorCount;
String chain1 = readLine("Please type in the first chain of DNA code: ");
for (int i=0; i<chain1.length(); i++)
{
current = chain1.charAt(i) +"";
if (!((current.equalsIgnoreCase("a"))||(current.equalsIgnoreCase("t"))||
(current.equalsIgnoreCase("c"))||(current.equalsIgnoreCase("g"))))
{
flag=false; break;
}
}
while (flag==false)
{
errorCount=0;
println("The DNA code you insert must only contain the characters A, T, C and G");
chain1 = readLine("Please type again in the first chain of DNA code: ");
for (int i=0; i<chain1.length(); i++)
{
current=chain1.charAt(i) +"";
if (!((current.equalsIgnoreCase("a"))||(current.equalsIgnoreCase("t"))||
(current.equalsIgnoreCase("c"))||(current.equalsIgnoreCase("g"))))
{
errorCount =1; break;
}
}
if (errorCount==0)
{
flag=true; break;
}
}
chain2 = readLine("Please type in the second chain of DNA code: ");
flag=true;
for (int i=0; i<chain2.length(); i++)
{
current = chain2.charAt(i) +"";
if (!((current.equalsIgnoreCase("a"))||(current.equalsIgnoreCase("t"))||
(current.equalsIgnoreCase("c"))||(current.equalsIgnoreCase("g")))&&(chain1.length()>chain2.length()))
{
flag= false; break;
}
}
while ((flag==false)&&(chain1.length()>chain2.length()))
{
errorCount=0;
if (chain1.length()>chain2.length())
println("The second DNA chain must be longer or equal to the first one at the most!");
else
println("The DNA code you insert must only contain the characters A, T, C and G");
chain2 = readLine("Please type again the second chain of DNA code: ");
for (int i=0; i<chain2.length(); i++)
{
current = chain2.charAt(i) +"";
if (!((current.equalsIgnoreCase("a"))||(current.equalsIgnoreCase("t"))||
(current.equalsIgnoreCase("c"))||(current.equalsIgnoreCase("g")))&&(chain1.length()>chain2.length()))
{
errorCount =1; break;
}
}
if (errorCount==0)
{
flag=true;
}
}
int match=findFirstMatchingPosition(chain1,chain2);
if (match==-1)
println("Not match found! "+ match);
else
println("Match has been found at point "+ match+ "!");
}
public int findFirstMatchingPosition(String shortDNA, String longDNA)
{
String currentCharShort=""; String currentCharLong="";
int match=0; int ans=-1; int a;
for (int i=0; i < longDNA.length(); i++)
{
a = i;
match = 0;
for (int j=0; j < shortDNA.length(); j++)
{
currentCharLong=longDNA.charAt(a)+ "";
currentCharShort=shortDNA.charAt(j)+ "";
if ( (currentCharShort.equalsIgnoreCase("a") && currentCharLong.equalsIgnoreCase("t"))||
(currentCharShort.equalsIgnoreCase("t") && currentCharLong.equalsIgnoreCase("a"))||
(currentCharShort.equalsIgnoreCase("c") && currentCharLong.equalsIgnoreCase("g"))||
(currentCharShort.equalsIgnoreCase("g") && currentCharLong.equalsIgnoreCase("c")) )
{
match +=1;
a +=1;
}
else break;
}
if (match == shortDNA.length())
{
ans=i;
break;
}
}
return ans;
}
}
if ( (currentCharShort.equalsIgnoreCase("a") && currentCharLong.equalsIgnoreCase("t"))||
(currentCharShort.equalsIgnoreCase("t") && currentCharLong.equalsIgnoreCase("a"))||
(currentCharShort.equalsIgnoreCase("c") && currentCharLong.equalsIgnoreCase("g"))||
(currentCharShort.equalsIgnoreCase("g") && currentCharLong.equalsIgnoreCase("c")) )
{
match +=1;
a +=1;
}
This is where your problem is, since you nested the loop, 'a' has the opportunity to increment greater than the total length of longDNA.
When you enter this for loop
for (int j=0; j < shortDNA.length(); j++)
{
currentCharLong=longDNA.charAt(a)+ "";
currentCharShort=shortDNA.charAt(j)+ "";
if ( (currentCharShort.equalsIgnoreCase("a") && currentCharLong.equalsIgnoreCase("t"))||
(currentCharShort.equalsIgnoreCase("t") && currentCharLong.equalsIgnoreCase("a"))||
(currentCharShort.equalsIgnoreCase("c") && currentCharLong.equalsIgnoreCase("g"))||
(currentCharShort.equalsIgnoreCase("g") && currentCharLong.equalsIgnoreCase("c")) )
{
match +=1;
a +=1;
}
else break;
}
with "a" that is the index of your last character in longDNA (say 5 if longDNA has six characters), when you enter the if branch and put a+=1 you now have an index that is greater than longDNA size. So when you iterate again and search for charAt(a) the exception will be thrown. This could also happen with lesser "a" if you execute the a+=1 statement different times in the internal for loop.
Related
I have a String
String s="#$% AbcD89";
And I'm trying to get the first letter of that String regardless of if it's capitalized or not. However, I do not know how many characters are before that first letter. I have tried using
int index=0;
outerloop:
for(int i=0; i<s.length;i++) {
if(Character.isLetter(s.chartAt(i)) { //Tried with isAlphabetic as well
index=i;
break outerloop;
}
}
But these return what seems to be a random character. Basically, that doesn't return the first letter
Note I cannot use Pattern and Matcher classes
Try it like this. Note that 0 is a legitimate location as an index so initialize your index to -1 and test before using.
String s = "#$% AbcD89";
int index = -1;
for (int i = 0; i < s.length(); i++) {
if (Character.isLetter(s.charAt(i))) {
index = i;
break;
}
}
if (index < 0) {
System.out.println("No letter found!");
} else {
System.out.println("First letter is : " + s.charAt(index));
}
prints
First letter is : A
if(letterGuessBoolean == true) {
System.out.println("Nice job! That was correct!");
for (position = 0; position < pickRandomWord.length(); position++) {
if (pickRandomWord.charAt(position) == letterGuess) {
System.out.print(letterGuess);
}
else {
System.out.print(unknownLetters);
}
}
}
loop does save the word properly, the unknown character never save the correct way.
You are printing out the latestly guessed letter only, because this is the only thing you are checking:
pickRandomWord.charAt(position) == letterGuess
You need to remember somehow and somewhere, which letters have been guessed previously. One variant could be the following:
String pickRandomWord = ""; // select your random word
char[] displayOutput = new char[pickRandomWord.length()];
for(int n = 0; n < displayOutput.length; ++n)
displayOutput[n] = '-';
/* ... */
if(letterGuessBoolean) // do not compare against true, if it is already boolean!
{
for(int position = 0; position < pickRandomWord.length(); ++position)
{
if (pickRandomWord.charAt(position) == letterGuess)
{
displayOutput[position] = letterGuess;
}
System.out.print(displayOutput[position]);
}
}
so if Sequence 1 :CAG and Sequence 2 :AG, i am supposed to get the response
"Best alignment score :2 CAG AG"
but instead i am getting
"Best alignment score :0 CAG AG"
I believe my issue is in the 2nd if statement, as that what it seems like with the debugger.
when using the debugger it shows that the computer not going into the if statement.
public static int allignment (String dnaSequence1 , String dnaSequence2 /*,int offset*/){
int newScore = 0;
int bestScore = 0;
int newOffset = 0;
int bestOffset = 0;
for(int offset =0; offset<=(dnaSequence1.length()-dnaSequence2.length());offset++){
//newOffset ++;
newScore = 0;
for(int place =0; place<dnaSequence2.length();place++ ){
if(dnaSequence1.charAt(place) == dnaSequence2.charAt(place/*+offset*/)){
newScore ++;
if(newScore>bestScore){
bestScore = newScore;
bestOffset = newOffset;
}
}else{ continue;}
}
newOffset ++;
}
String space = " ";
System.out.println("Best alignment score :"+bestScore);
System.out.println(dnaSequence1);
System.out.print( space(bestOffset) + dnaSequence2);
int alignmentScore = dnaSequence1.compareToIgnoreCase(dnaSequence2);
return alignmentScore;
}
public static String space (int bestOffset){
String space = " ";
String offsetScaces = "";
for(int i = 0; i<bestOffset; i++){
offsetScaces+=space;
return offsetScaces;
}
return offsetScaces;
}
Your version is using the same index for both strings. So it checks if the nucleotide at index 0 in sequence1 ('C') matches the nucleotide at index 0 in sequence2 ('A') then it increments the index and checks if the nucleotide at index 1 in sequence1 ('A') matches the nucleotide at index 1 in sequence2 ('G') then it stops without ever finding a match.
012
CAG
AG
You can see from the example above that at no time is the character in the first string the same as the second (0: C/A, 1: A/G, 2: G/null)
It strikes me that maybe you're looking for the longest piece of dnaSequence2 that aligns to something in dnaSequence1, not just the longest piece that starts at index 0.
This version tries to find the whole 2nd sequence inside the 1st sequence and if it can't, it trims 1 nucleotide from the end of the 2nd sequence and tries again. Once it's trimmed the 2nd sequence to nothing, it starts again with the whole 2nd sequence and trims 1 nucleotide from the start and repeats the process (stopping if it finds a match)
public static int allignment(String dnaSequence1, String dnaSequence2 /*,int offset*/) {
int bestScore = -1;
int bestOffset = 0;
String bestSequence = null;
for(String tempSequence = dnaSequence2; tempSequence.length() > 0; tempSequence = tempSequence.substring(1)) {
for(String match = tempSequence; match.length() > 0; match = match.substring(0, match.length() - 1)) {
int matchIndex;
if (-1 != (matchIndex = dnaSequence1.indexOf(match))) {
if (match.length() > bestScore) {
bestOffset = matchIndex;
bestScore = match.length() ;
bestSequence = match;
break;
}
}
}
if (null != bestSequence && bestScore > tempSequence.length()) {
break; // don't bother checking any shorter sequences, we already have a better match
}
}
if (null != bestSequence) {
System.out.println("Best alignment score :" + bestScore);
System.out.println(dnaSequence1);
System.out.print(space(bestOffset) + bestSequence);
} else {
System.out.print(dnaSequence1+" and "+dnaSequence2+" cannot be aligned");
}
int alignmentScore = dnaSequence1.compareToIgnoreCase(dnaSequence2);
return alignmentScore;
}
public static String space(int bestOffset) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < bestOffset; i++) {
builder.append(" ");
}
return builder.toString();
}
A string is a palindrome if it is spelled the same way backward and
forward.
Examples of palindromes include “Radar” and “Dammit, I’m mad!”.
Write a java program, PalindromeTester, that asks the user to enter a
word or sentence and then checks whether the entered string is a
palindrome or not.
Spaces, nonalphabetics (.,!:?-()\";), and case within the string have
to be ignored e.g., "Drab as a fool, aloof as a bard." is a
palindrome.
Your implementation should define and use the method isPalindrome to
test if a certain string is a palindrome. The signature of the
isPalindrome method is as follows:
boolean isPalindrome(String)
Following is a sample run of the program. The user’s input is shown in bold.
java PalindromeTester
Introduction to Computer Programming (CMPS 200)
Spring 2015-16 2 of 3
Enter a string: I love CMPS 200
The string "I love CMPS 200" is NOT a palindrome.
This is the code I made, it keeps giving me an error.
I would like to know what my error is and whether there's a faster easier way of writing this code
import java.util.Scanner;
public class PalindromeTester {
public static void main (String args []) {
Scanner console = new Scanner(System.in);
System.out.println("Enter a string: ");
String palindrome = console.next();
if (isPalindrome (palindrome)) {
System.out.print("The string \""+palindrome+" is a palindrome.");
} else {
System.out.print("The string \""+palindrome+" is NOT a palindrome.");
}
}
public static boolean isPalindrome (String palindrome) {
int constant = 1;
for (int i = 0 ; i <= (palindrome.length()-1) ; i++) {
for (int z= (palindrome.length()-1);i >= 0; i--) {
if (palindrome.charAt(i) <'#'||'Z'<palindrome.charAt(i)&&palindrome.charAt(i)<'`'||'['<palindrome.charAt(i)&&palindrome.charAt(i)<'{') {
i=i+1;
}
if (palindrome.charAt(z)<'#'||'Z'<palindrome.charAt(z)&&palindrome.charAt(z)<'`'||'['<palindrome.charAt(z)&&palindrome.charAt(z)<'{') {
z=z+1;
}
if (palindrome.charAt(i)==(palindrome.charAt(z))) {
constant = constant * 1;
} else {
constant = constant * 0;
}
}
}
if (constant == 0 ) {
return false;
} else {
return true;
}
}
}
One approach would be to strip the non alpha characters out of the string. Then check if the string is the same as itself reversed (while upper case):
public static boolean isPalindrome(String palindrome) {
StringBuilder sanitisedString = new StringBuilder();
for(char c : palindrome.toCharArray()) {
if(Character.isLetter(c)) {
sanitisedString.append(c);
}
}
return sanitisedString.toString().toUpperCase().equals(sanitisedString.reverse().toString().toUpperCase());
}
Index out of range is caused by palindrome.charAt(z)) after z = z + 1;
Keep simple :
public static boolean isPalindrome(String palindrome)
{
palindrome = palindrome.replaceAll("\\W", ""); // remove all non word character
palindrome = palindrome.toLowerCase();
int size = palindrome.length();
int halfSize = size / 2;
for (int i = 0; i < halfSize; i++)
{
if(palindrome.charAt(i) != palindrome.charAt(size - i - 1))
return false;
}
return true;
}
Why not just make a new String and save the reversed source(String) in it.
public static boolean readstring(String s)
{
String b = "";
for (int i= s.length() -1; i >=0 ;i--)
{
b = b + s.charAt(i);
}
System.out.print(b +" and "+ s +" ");
return b == s || b.Equals(s);
}
EDIT: Hopefully this meets the requirements, by the way dont use the word "ignore" but "allow"
public boolean isPalindrome(String word) {
int backward = word.length() - 1;
for (int x = 0; x < word.length(); x++) {
if (word.charAt(x)!= word.charAt(backward--)) {
return false;
}
}
return true;
}
public class Solution {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int tc = Integer.parseInt(br.readLine());//I get Numberformat Exception here
for(int i=0;i<tc;i++) // Even if my inputs are on separate lines
{
String original = br.readLine();
palindrome(original);
}
}
public static void palindrome(String original)
{
String reverse="";
int length = original.length();
for ( int i = length - 1 ; i >= 0 ; i-- )
reverse = reverse + original.charAt(i);
if (original.equals(reverse))
{
System.out.println(0);
}
else
{
char[] org = original.toCharArray();
int len = org.length;
int mid = len / 2;
if(len % 2 == 0)
{
char[] front = new char[mid];
char[] back = new char[mid];
for(int i=0;i<mid;i++)
{
front[i] = org[i];
}
int j=0;
for(int i=len-1;i>=mid;i--)
{
back[j] = org[i];
j++;
while(j > mid)
{
break;
}
}
change(front,back,mid);
}
else
{
char[] front = new char[mid];
char[] back = new char[mid];
for(int i=0;i<mid;i++)
{
front[i] = org[i];
}
int j=0;
for(int i=len-1;i>mid;i--)
{
back[j] = org[i];
j++;
while(j > mid)
{
break;
}
}
change(front,back,mid);
}
}
}
public static void change(char[] front,char[] back,int len)
{
int count =0;
for(int i =0;i<len;i++)
{
if(front[i] != back[i] )
{
count += (back[i] - front[i]);
}
}
System.out.println(count)
}
}
What i try to do here is get an input from the number of test cases say 3 in my first line followed by the test-cases themselves.
sample input :
3
abc
abcba
abcd
Now it has to check if the string is a palindrome if its so it ll print 0
else it breaks the string into two halves front and back and finds the minimum number of changes to make it a palidrome.
here i have also checked if its a odd or even length string if odd i have omitted the middle char.
By changes we can only change 'd' to 'b' not 'b' to 'd'
Once a letter has been changed to 'a', it can no longer be changed.
My code works fine for the above input but it doesnt for some other inputs i dont quiet understand why..
for instance if i give a custom test case as
5
assfsdgrgregedhthtjh
efasfhnethiaoesdfgv
ehadfghsdfhmkfpg
wsertete
agdsjgtukgtulhgfd
I get a Number Format Exception.
Your code works fine here, whithout NumberFormatException: http://ideone.com/QJqjmG
This may not solve your problem, but improves your code...
As first user input you are expecting an integer. You are parsing the String returned by br.readLine() and do not take care of the NumberFormatException parseInt(...) may throw.
Just imagine someone hits space or return key as first input.
So I propose to put a try-catch-block around the parseInt(...). Here is an example how this may look like.
Guys thank you for all your suggestion i just found out why my other test cases weren't working
public static void change(char[] front,char[] back,int len)
{
int count =0;
for(int i =0;i<len;i++)
{
if(front[i] != back[i] )
{
count += (back[i] - front[i]);
}
}
System.out.println(count)
}
This part of my code has to be changed to
public static void change(char[] front,char[] back,int len)
{
int count =0;
for(int i =0;i<len;i++)
{
if(front[i] != back[i] )
{
char great = findGreatest(front[i],back[i]);
if(great == back[i])
{
count += (back[i] - front[i]);
}
else
{
count += (front[i] - back[i]);
}
}
}
System.out.println(count);
}
public static char findGreatest(char first,char second)
{
int great = first;
if(first < second)
{
great = second;
}
return (char)great;
}
Because i get negative values coz of subtracting ascii's which are greater than them and as i have already mentioned i can only do 'd' to 'a' not the other way round.
Thank you for your time guys!