0
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;
}

}

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Sakis
  • 31
  • 12
  • 2
    the cause of this is, that you have a String of six characters, and you are trying to access the 7th character. check the stacktrace, it'll tell you exactly on which line it happens – Stultuske Jan 22 '16 at 09:50
  • 1
    change your for loop to `for (int j=0; j < shortDNA.length() && a – SMA Jan 22 '16 at 09:53

2 Answers2

2
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.

Hallrac
  • 36
  • 2
1

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.

Matteo Di Napoli
  • 567
  • 5
  • 17
  • thank you very much for replying. i tried doing this : for (int i=0; i < longDNA.length()-1; i++) and it seems to be working at the moment what do you think? – Sakis Jan 22 '16 at 10:42
  • This way you could not check the last character of longDNA. What the method should do exactly? – Matteo Di Napoli Jan 22 '16 at 10:50
  • this method must check if the 2 dna chains match A matches with T and C with G and the other way around. if they do match it returns the matching position. For example TTGCC and TAACGGTACGTC matches only at position number 1. (starting from 0) – Sakis Jan 22 '16 at 10:57
  • So, if you have to check only for a number of character that is max the length of the shortest of the two and only in the same character position in the two strings, you should use a single for loop with end condition i – Matteo Di Napoli Jan 22 '16 at 11:05