I can't figure out why my if statement is working - java

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();
}

Related

Splitting a string in an array of strings of limited size

I have a string of a random address like
String s = "H.N.-13/1443 laal street near bharath dental lab near thana qutubsher near modern bakery saharanpur uttar pradesh 247001";
I want to split it into array of string with two conditions:
each element of that array of string is of length less than or equal to 20
No awkward ending of an element of array of string
For example, splitting every 20 characters would produce:
"H.N.-13/1443 laal st"
"reet near bharath de"
"ntal lab near thana"
"qutubsher near moder"
"n bakery saharanpur"
but the correct output would be:
"H.N.-13/1443 laal"
"street near bharath"
"dental lab near"
"thana qutubsher near"
"modern bakery"
"saharanpur"
Notice how each element in string array is less than or equal to 20.
The above is my output for this code:
static String[] split(String s,int max){
int total_lines = s.length () / 24;
if (s.length () % 24 != 0) {
total_lines++;
}
String[] ans = new String[total_lines];
int count = 0;
int j = 0;
for (int i = 0; i < total_lines; i++) {
for (j = 0; j < 20; j++) {
if (ans[count] == null) {
ans[count] = "";
}
if (count > 0) {
if ((20 * count) + j < s.length()) {
ans[count] += s.charAt (20 * count + j);
} else {
break;
}
} else {
ans[count] += s.charAt (j);
}
}
String a = "";
a += ans[count].charAt (0);
if (a.equals (" ")) {
ans[i] = ans[i].substring (0, 0) + "" + ans[i].substring (1);
}
System.out.println (ans[i]);
count++;
}
return ans;
}
public static void main (String[]args) {
String add = "H.N.-13/1663 laal street near bharath dental lab near thana qutubsher near modern bakery";
String city = "saharanpur";
String state = "uttar pradesh";
String zip = "247001";
String s = add + " " + city + " " + state + " " + zip;
String[]ans = split (s);
}
Find all occurrences of up to 20 chars starting with a non-space and ending with a word boundary, and collect them to a List:
List<String> parts = Pattern.compile("\\S.{1,19}\\b").matcher(s)
.results()
.map(MatchResult::group)
.collect(Collectors.toList());
See live demo.
The code is not very clear, but at first glance it seems you are building character by character that is why you are getting the output you see. Instead you go word by word if you want to retain a word and overflow it to next String if necessary. A more promising code would be:
static String[] splitString(String s, int max) {
String[] words = s.split("\s+");
List<String> out = new ArrayList<>();
int numWords = words.length;
int i = 0;
while (i <numWords) {
int len = 0;
StringBuilder sb = new StringBuilder();
while (i < numWords && len < max) {
int wordLength = words[i].length();
len += (i == numWords-1 ? wordLength : wordLength + 1);//1 for space
if (len <= max) {
sb.append(words[i]+ " ");
i++;
}
}
out.add(sb.toString().trim());
}
return out.toArray(new String[] {});
}
Note: It works on your example input, but you may need to tweak it so it works for cases like a long word containing more than 20 characters, etc.

Palindrome in java

Here what I tried
sample input is "aabaa"
eg: in if condition val[0] = a[4]
if it is equal i stored it in counter variable if it is half of the length it original string it is palindrome
if it is not it is not a palindrome
I tried with my basic knowledge in java if there is any errors let me know
boolean solution(String inputString) {
int val = inputString.length();
int count = 0;
for (int i = 0; i<inputString.length(); i++) {
if(inputString.charAt(i) == inputString.charAt(val-i)) {
count = count++;
if (count>0) {
return true;
}
}
}
return true;
}
How about
public boolean isPalindrome(String text) {
String clean = text.replaceAll("\\s+", "").toLowerCase();
int length = clean.length();
int forward = 0;
int backward = length - 1;
while (backward > forward) {
char forwardChar = clean.charAt(forward++);
char backwardChar = clean.charAt(backward--);
if (forwardChar != backwardChar)
return false;
}
return true;
}
From here
In your version you compare first element with last, second with second last etc.
last element in this case is inputString.length()-1(so need to use 'inputString.charAt(val-i-1)' . If you iterate till end, then the count should be equal to length of the string.
for(int i = 0; i<inputString.length(); i++){
if(inputString.charAt(i) == inputString.charAt(val-i-1)){
count ++;
}
}
return (count==val); //true when count=val
Or alternatlively iterate till the mid point of the array, then count value is val/2.
for(int i = 0; i<inputString.length()/2; i++){
if(inputString.charAt(i) == inputString.charAt(val-i-1)){
count ++;
}
}
return (count==val/2); //true when count=val/2
There's no constraints in the question so let me throw in a more cheesy solution.
boolean isPalindrome(String in)
final String inl = in.toLowerCase();
return new StringBuilder(inl).reverse().toString().equals(inl);
}
A palindrome is a word, sentence, verse, or even a number that reads the same forward and backward. In this java solution, we’ll see how to figure out whether the number or the string is palindrome in nature or not.
Method - 1
class Main {
public static void main(String[] args) {
String str = "Nitin", revStr = "";
int strLen = str.length();
for (int i = (strLen - 1); i >=0; --i) {
revStr = revStr + str.charAt(i);
}
if (str.toLowerCase().equals(revStr.toLowerCase())) {
System.out.println(str + " is a Palindrome String.");
}
else {
System.out.println(str + " is not a Palindrome String.");
}
Method - 2
class Main {
public static void main(String[] args) {
int n = 3553, revNum = 0, rem;
// store the number to the original number
int orgNum = n;
/* get the reverse of original number
store it in variable */
while (n != 0) {
remainder = n % 10;
revNum = revNum * 10 + rem;
n /= 10;
}
// check if reversed number and original number are equal
if (orgNum == revNum) {
System.out.println(orgNum + " is Palindrome.");
}
else {
System.out.println(orgNum + " is not Palindrome.");
}

How to use/modify Knuth-Morris-Pratt algorithm to convert any given string to palindrome

I have been given a task to create a class that given a String will create a palindrome with minimum number of assertions.
Example Runs:
Input: 123333
Output: 12333321
Input: 789
Output: 78987
Input: 1221
Output: 1221221
**Note a Palindrome should NOT return the same Palindrome.
I tried using a modified KMP algorithm as stated here.
I revert the string and compare it to the reverse + original string and then add the mismatches to the original string.
However my function only works for inputs with trailing digits (first example input) however an input like 1234 will return 1234123, '92837465' will return '928374659283746'
public static int[] computelps(String sample){
int[] lps = new int[sample.length()];
lps[0] = 0;
int i = 1;
int len = 0; // length of previous longest prefix suffix
while (i < sample.length()) {
if (sample.charAt(i) == sample.charAt(len)) {
len++;
lps[i] = len;
i++;
}
else
{
if (len != 0) {
len = lps[len - 1];
}
else {
lps[i] = 0;
i++;
}
}
}
return lps;
}
public static void Solution(File samplefile) throws Exception {
BufferedReader br = new BufferedReader(new FileReader(samplefile));
String firstline = br.readLine();
String line;
while ((line = br.readLine()) != null) {
String reverse_str = "";
String newline = line.replace(".", "");
for (int i = newline.length() - 1; i >= 0; i--) {
reverse_str += newline.charAt(i);
}
int [] lps = computelps(reverse_str); // computes the lps of the pattern string
String tot = reverse_str + newline;
// KMP Algorithm modified.
int x = 0; // index for total_string(tot)
int y = 0; // index for pattern
String palindrome = newline;
while (x < tot.length()){
if(reverse_str.charAt(y) == tot.charAt(x)){
y++;
x++;
}
if(y == reverse_str.length()) {
y = lps[y - 1];
}
else if( x < tot.length() && (reverse_str.charAt(y) != tot.charAt(x))){
palindrome += tot.charAt(x);
if ( y!= 0){
y = lps[y-1];
}
else{
x += 1;
}
}
}
System.out.println(palindrome);
}
}
I would appreciate any help. I find algorithms very challenging so please bear with me if my approach or code is sub-par.
*I fixed sample inputs and outputs as well as added my results.
It helps to split this problem in smaller problems, implement a separate method for each and check to see if each method works as expected. What will really help you will be to learn to use the debugger in your Ide. But until you do that you can test that each part of your code works as expected. So I simplified a little your code and split it up :
public static void main(String[] args){
System.out.println("computelps " + ("[0, 0, 0, 0]".equals(Arrays.toString(computelps("4321"))) ? "works" : "doesn't work" ));
System.out.println("reverse " + ("4321".equals(reverse("1234")) ? "works" : "doesn't work" ));
System.out.println("Solution " + ("1234321".equals(Solution("1234")) ? "works" : "doesn't work" ));
}
public static int[] computelps(String sample){
int[] lps = new int[sample.length()];
lps[0] = 0;
int i = 1;
int len = 0; // length of previous longest prefix suffix
while (i < sample.length()) {
if (sample.charAt(i) == sample.charAt(len)) {
len++;
lps[i] = len;
i++;
}
else
{
if (len != 0) {
len = lps[len - 1];
}
else {
lps[i] = 0;
i++;
}
}
}
return lps;
}
public static String Solution(String line) {
String newline = line.replace(".", "");
String reverse_str = reverse(newline);
int [] lps = computelps(reverse_str); // computes the lps of the pattern string
// KMP Algorithm modified.
return kpmModified(newline, reverse_str, lps);
}
private static String kpmModified(String newline, String reverse_str, int[] lps) {
int x = 0; // index for total_string(tot)
int y = 0; // index for pattern
String tot = reverse_str + newline;
String palindrome = newline;
while (x < tot.length()){
if(reverse_str.charAt(y) == tot.charAt(x)){
y++;
x++;
}
if(y == reverse_str.length()) {
y = lps[y - 1];
}
else if( x < tot.length() && (reverse_str.charAt(y) != tot.charAt(x))){
palindrome += tot.charAt(x);
if ( y!= 0){
y = lps[y-1];
}
else{
x += 1;
}
}
}
return palindrome;
}
private static String reverse(String newline) {
String reverse_str = "";
for (int i = newline.length() - 1; i >= 0; i--) {
reverse_str += newline.charAt(i);
}
return reverse_str;
}
And the result is
computelps works
reverse works
Solution doesn't work
So your bug is in kpmModified method. I can't spend more time and I'm not familiar with the algorithm but you should continue like this and figure our what part of that method has the bug.
I think you overthink the problem. The question is basically adding a string's reversed version back to it's original, but not every character, right? So you might need to find something like a pointer to tell the function where to start to reverse.
One example. Let the string be 12333. If we add every character from the index string.length() to 0, it will be 1233333321, which is not correct, since there are duplicated 3's. We need to ignore those, so we need to add characters from string.length() - numOfDuplicateAtEnd to 0.
public String palindromic(String num) {
int i = num.length() - 1;
while (i > -1 && num.charAt(i) == num.charAt(num.length() - 1))
i--;
for (int k = i; k > -1; --k)
num += num.substring(k, k + 1);
return num;
}

New to programming, getting a run time error don't know why

Basically summarized in the title. https://ideone.com/E2BMS8 <-- that's a link to the code. I understand if you don't want to click it though so I'll paste it here as well. will just be disorganized. The code is supposed to flip the letters but keep words in the same position. I would like to figure that part out on my own though. Just need help with the run time error.
import java.util.*;
class Ideone {
public static void main (String[] args) throws java.lang.Exception {
Scanner input = new Scanner(System.in);
String sent, accum = "";
char check, get;
int len, count = 0;
System.out.print("Please enter the sentance you want reversed: ");
sent = input.nextLine();
len = sent.length();
for (int i = 0; i < len; i++) {
check = sent.charAt(len - i);
count += 1;
if (check == ' ') {
for (int p = 0; p < count; p++) {
while (p < count) {
get = sent.charAt(len - p);
accum += (get + ' ');
}
}
}
}
System.out.println("Reversed: " + accum);
}
}
The error String index out of range is cause because of the len is one more than the index range. Remove one on the index such I did below:
import java.util.*;
public class Ideone {
public static void main (String[] args) throws java.lang.Exception {
Scanner input = new Scanner(System.in);
String sent, accum = "";
char check, get;
int len, count = 0;
System.out.print("Please enter the sentance you want reversed: ");
sent = input.nextLine();
len = sent.length();
for (int i = 0; i < len; i++) {
check = sent.charAt(len - i - 1);
count += 1;
if (check == ' ') {
for (int p = 0; p < count; p++) {
get = sent.charAt(len - p - 1);
accum += (get + ' ');
}
}
}
System.out.println("Reversed: " + accum);
}
}
This is a classical "off by one" error -- something you will run into a lot as you find your programming feet. The issue in this case is the 0-based indexing. That is, the first character of a string is at index 0, and the last is at index "string length - 1". If we use sent = "Test"; as an example, then:
sent.charAt(0) == 'T'
sent.charAt(1) == 'e'
sent.charAt(2) == 's'
sent.charAt(3) == 't'
sent.charAt(4) == ??? // "That's an error, Jim!"
Note that index 4 -- which perhaps confusingly is also the length of the string -- is out of bounds. So, what happens during the first iteration of the loop, when i == 0:
check = sent.charAt(len - i); // ERROR! Because ...
==> = sent.charAt((4) - (0));
==> = sent.charAt( 4 ); // Doh!
I leave it to you to figure out how you might fix it.

Finite State Machine to Search for "ABBA"

I'm trying to write a while switch case kinda code for modeling a finite state machine that searches a string of As and Bs to see if the string "ABBA" is present. When I input just "ABBA", it outputs Word found! like it's supposed to. However, if I input "AABBA" it doesn't find the word & output the right message. Any help is appreciated. Thanks!
import java.util.*;
public class AB{
public static void main(String args[]){
Scanner input = new Scanner(System.in);
String word = input.next();
int current = 0;
int status = 0;
System.out.println("Starting to evaluate...");
while(status != 4){
for(int i = current; i < word.length(); i++){
String part = word.substring(current, i + 1);
switch(status){
case 0: //start
if(part.equals("A")){
status = 1;
}
else if(part.equals("B"){
status = 0;
current = i;
}
break;
case 1: //A is there now
if(part.equals("AB")){
status = 2;
}
else if(part.equals("AA"){
status = 1;
current = 1;
}
break;
case 2: //AB is there now
if(part.equals("ABB")){
status = 3;
}
else if(part.equals("ABA"){
status = 1;
current = 1;
}
break;
case 3: //ABB is there now
if(part.equals("ABBA")){
status = 4;
System.out.println("Word found!");
}
else if(part.equals("ABBB"){
status = 0;
current = i;
}
break;
}
}
}
}
}
What I can see ineffective in your approache is that you actually do not use the power of a state machine. First of all you should understand what drives your machine through the states. In your example each sequential letter of the input string does. Since you have taken a state you should now check to which state would the next symbol switch your machine. Let me suggest the following implementation..
Here is the state diagram:
Here is the code implementing the diagram:
public boolean abbaMatcher(String abba)
{
int state = 0;
int symbol = 0;
while (symbol < abba.length()){
char c = abba.charAt(symbol);
switch (state){
case 0: if(c == 'a'){
state = 1;
}else{
state = 0;
};
break;
case 1: if(c == 'b'){
state = 2;
}else{
state = 1;
};
break;
case 2: if(c == 'b'){
state = 3;
}else{
state = 1;
};
break;
case 3: if(c == 'a'){
return true;
}else{
state = 0;
};
break;
}
symbol++;
}
return false;
}
This could be written more easily with just a for loop, however the while/switch construnction is a requirement.
The following code is similar to your implementation but it accounts for dynamic sequences (different sequences), and does not mess with substrings but rather iterates over the string's underlying character array.
It also accounts for a sequence that starts in another sequence, for instance: Looking for the sequence "ABAB" in the string "ABABAB" would have the results "ABAB" found at index 0 and "ABAB" found at index 2. This can easily be removed by commenting out wIndex = startIndex.
Code:
public static void main (String[] args) throws java.lang.Exception {
// Scanner input = new Scanner(System.in);
String word = "B BABBABBA B";
String seq = "ABBA";
char[] wChars = word.toCharArray();
char[] sChars = seq.toCharArray();
int wIndex = 0; // wChars index
int sIndex = 0; // sChars index
int startIndex = 0; // starting index of the seq found in wChars
System.out.println("Starting to evaluate...");
while(wIndex < wChars.length) {
if(wChars[wIndex] == sChars[sIndex]) {
if(sIndex == 0) {
startIndex = wIndex;
}
sIndex += 1;
} else {
sIndex = 0;
}
if(sIndex >= sChars.length) {
System.out.println("Sequence \"" + seq + "\" found at index " + startIndex + ".");
sIndex = 0;
wIndex = startIndex; // set wIndex to startIndex to account for
// sequence within a sequence, basically
// backtracking
}
wIndex += 1;
}
}
Output:
Starting to evaluate...
Sequence "ABBA" found at index 3.
Sequence "ABBA" found at index 6.

Categories

Resources