Issue with my string reverse program - java

newer programmer here, having trouble diagnosing the issue with my string reversal program. The program is supposed to compare two strings and find out if string x is the reversal of string y and if it is it returns true, if not it returns false.
public class Reverse
{
public static void main(String[] args)
{
System.out.println(isExactReverse("ba", "a"));
System.out.println(isExactReverse("desserts", "stressed"));
System.out.println(isExactReverse("apple", "apple"));
System.out.println(isExactReverse("regal", "lager"));
System.out.println(isExactReverse("war", "raw"));
System.out.println(isExactReverse("pal", "slap"));
}
public static boolean isExactReverse(String x, String y)
{
//To be completed
int counter = 0;
int temp = x.length() - 1;
boolean result = false;
for(int i = 0; i < y.length(); i++)
{
if(x.charAt(temp) == y.charAt(i))
{
counter++;
}
temp--;
}
if(counter == y.length())
{
result = true;
}
return result;
}
}
the output i get is not correct and I am getting a runtime error.
true
true
false
true
true
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.charAt(String.java:658)
at Reverse.isExactReverse(Reverse.java:24)
at Reverse.main(Reverse.java:11)
Expected output:
False
True
False
True
True
False

The problem in your code is that it assumes that x and y have the same length. When it is not so, the code either returns a false positive, as in case of "ba"-"a", or crashes, as in case of "pal"-"slap".
Fix this by adding this check at the top of your isExactReverse method:
if (x.length() != y.length()) {
return false;
}
Demo.

The code is certainly able to be compiled. It would be nice if you could specify the problem.
But I guess you got problems getting the correct result. First of all, I would recommend you simplified the code. There is a lot of lines, that don't have to be there.
Here is, what I would do.
public class Reverse
{
public static void main(String[] args)
{
System.out.println(isExactReverse("ba", "a"));
System.out.println(isExactReverse("desserts", "stressed"));
System.out.println(isExactReverse("apple", "apple"));
System.out.println(isExactReverse("regal", "lager"));
System.out.println(isExactReverse("war", "raw"));
System.out.println(isExactReverse("pal", "slap"));
}
public static boolean isExactReverse(String x, String y)
{
//To be completed
int temp = x.length() - 1;
boolean result = false;
for(int i = 0; i < y.length(); i++)
{
if(!x.charAt(temp).equals(y.charAt(i)))
{
return false;
}
temp--;
}
return true;
}
}
This should work. I don't really have an answer for your post, because I don't know you problem, but this is just some kind of help that maybe will resolve your problem.

Related

return int from within if statement in a loop in java

i have a loop which iterates equal to the length of an array, inside this loop i have a method which do some processing and have if-else structure inside. i want that if certain condition is true, then re-iterate the whole loop else continue.
the Minimum working code is provided.
for(int xx=0;xx<temp.length;xx++)
{
rule=temp[xx][1];
cons=temp[xx][2];
fp.factprocess(fact, rule, vars, cons);
}
contents of fp.factprocess are like
if(condition==true)
make xx = 0 in the parent loop
else
continue
i dont know how do i do it, i used return statement but it has to be in the end and can not be in the if-block.
Return a boolean from the condition test. If boolean true, set xx to -1 (to be incremented to 0) in the loop.
for(int xx=0;xx<temp.length;xx++)
{
rule=temp[xx][1];
cons=temp[xx][2];
boolean setXXtoZero = fp.factprocess(fact, rule, vars, cons);
if(setXXtoZero) xx=-1;
}
fp.factprocess:
return condition;
Yes, there can be a return statement in the if block.
public int getValue(int val){
if ( value == 5 ){
return value;
}
else{
return 6;
}
}
for instance, is valid Java code.
public int getValue(int input){
if ( input == 5 ){
return input;
}
}
on the other hand, is not, since you don't return anything if input does not equal 5, yet the method has to either return an int, or throw an Exception.
That's probably what your problem is: you need to provide a return statement for all possible scenario's.
If you want to modify the xx variable of the loop, I suggest to return a boolean in your factprocess method.
for (int xx = 0; xx < temp.length; xx++) {
rule = temp[xx][1];
cons = temp[xx][2];
boolean shouldRestart = fp.factprocess(fact, rule, vars, cons);
if (shouldRestart) {
xx = 0;
}
}
Pass xx to factprocess() and assign the return to xx
for(int xx=0;xx<temp.length;xx++)
{
rule=temp[xx][1];
cons=temp[xx][2];
xx = fp.factprocess(fact, rule, vars, cons, xx);
}
Inside factprocces()
if (condition == true) {
return 0
} else {
return xx
}

String index out of range in Java

I am aware there are multiple threads like my assignment below, but I just can't figure it out. I can't exactly figure out the mistake. Help would be appreciated.
I am trying to do this program:
Everything works fine unless I input the same chains or similar (for example ACTG and ACTG or ACTG and ACTGCCCC), when it tells me
string index out of range
This is that part of my code:
int tries=0;
int pos=-1;
int k;
for (int i=0; i<longDNA.length(); i++) {
tries=0;
k=i;
for (int j=0; j<shortDNA.length(); j++) {
char s=shortDNA.charAt(j);
char l=longDNA.charAt(k);
if (canConnect(s,l)) {
tries+=1;
k+=1;
}
}
if (tries==shortDNA.length()-1) {
pos=i-1;
break;
}
}
Let's call the two DNA strings longer and shorter. In order for shorter to attach somewhere on longer, a sequence of bases complementary to shorter must be found somewhere in longer, e.g. if there is ACGT in shorter, then you need to find TGCA somewhere in longer.
So, if you take shorter and flip all of its bases to their complements:
char[] cs = shorter.toCharArray();
for (int i = 0; i < cs.length; ++i) {
// getComplement changes A->T, C->G, G->C, T->A,
// and throws an exception in all other cases
cs[i] = getComplement(cs[i]);
}
String shorterComplement = new String(cs);
For the examples given in your question, the complement of TTGCC is AACGG, and the complement of TGC is ACG.
Then all you have to do is to find shorterComplement within longer. You can do this trivially using indexOf:
return longer.indexOf(shorterComplement);
Of course, if the point of the exercise is to learn how to do string matching, you can look at well-known algorithms for doing the equivalent of indexOf. For instance, Wikipedia has a category for String matching algorithms.
I tried to replicate your full code as fast as I could, I'm not sure if I fixed the problem but you don't get any errors.
Please try it and see if it works.
I hope you get this in time and good luck!
import java.util.Arrays;
public class DNA {
public static void main(String[] args) {
System.out.println(findFirstMatchingPosition("ACTG", "ACTG"));
}
public static int findFirstMatchingPosition(String shortDNA, String longDNA) {
int positionInLong = 0;
int positionInShort;
while (positionInLong < longDNA.length()) {
positionInShort = 0;
while(positionInShort < shortDNA.length()) {
String s = shortDNA.substring(positionInShort, positionInShort + 1);
if(positionInShort + positionInLong + 1 > longDNA.length()) {
break;
}
String l = longDNA.substring(positionInShort + positionInLong, positionInShort + positionInLong + 1);
if(canConnect(s, l)) {
positionInShort++;
if(positionInShort == shortDNA.length()) {
return positionInLong;
}
} else {
break;
}
}
positionInLong++;
if(positionInLong == longDNA.length()) {
return -1;
}
}
return -1;
}
private static String[] connections = {
"AT",
"TA",
"GC",
"CG"
};
private static boolean canConnect(String s, String l) {
if(Arrays.asList(connections).contains((s+l).toUpperCase())) {
return true;
} else {
return false;
}
}
}
I finally changed something with the k as Faraz had mentioned above to make sure the charAt does not get used when k overrides the length of the string and the program worked marvelously!
The code was changed to the following:
int tries=0;
int pos=-1;
int k;
for (int i=0; i<longDNA.length(); i++) {
tries=0;
k=i;
for (int j=0; j<shortDNA.length(); j++) {
if (k<longDNA.length()) {
char s=shortDNA.charAt(j);
char l=longDNA.charAt(k);
if ((s=='A' && l=='T') || (s=='T' && l=='A') || (s=='G' && l=='C') || (s=='C' && l=='G')) {
tries+=1;
k+=1;
}
}
}
if (tries==shortDNA.length()) {
pos=i;
break;
}
}
I am not sure how aesthetically pleasing or correct this excerpt is but - it completely solved my problem, and just 2 minutes before the deadline! :)
A huge thanks to all of you for spending some time to help me!!

Program freezes when trying to analyse a string

I am writing on a method which should analyse a polynomial given by the user (as String) and do different stuff with it in the future. At the moment, I was trying to test the code I have so far but whenever I execute the program, it freezes and after sitting for hours in front of the computer I still can't find the culprit in it.
I was testing if a polynomial of one variable could be analysed and then re-printed, but it doesn't work.
I hoped anyone could help me out on this.
Here's the code block in the main which executes the method, the string userInput is a polynomial (e.g 4x-6x^2):
String userInput = inputArea.getText().trim();
Monomials monomials = new Monomials();
monomials.analyse(userInput);
Here's the class monomials with its method analyse():
//Class Monomial
class Monomials
{
private int coeff = 0;
private char var;
private int addpow = 1;
private int pow;
private char powsign = '^';
private char minus = '-';
private boolean isnegative = false;
private String mono;
StringBuilder stringBuilder = new StringBuilder();
public int getCoeff(int coeff)
{
return coeff;
}
public void setCoeff(int coeff)
{
this.coeff = coeff;
}
public void setVar(char var)
{
this.var = var;
}
public void setPow(int pow)
{
this.pow = pow;
}
public String getMono(String monomials)
{
return mono;
}
// Method to further analyse user's input.
public void analyse(String polynomial)
{
//Split the poynomial into monomials and store them in an array list.
polynomial = polynomial.replaceAll("-","+-");
String polyParts[] = polynomial.split("\\+");
ArrayList<String> monomials = new ArrayList<String>(Arrays.asList(polyParts));
// Iterate the monomials.
for (int i = 0; i <= monomials.size(); i++)
{
String monomial = monomials.get(i);
// Analyse the monomial.
for (int x = 0; x <= monomial.length(); x++)
{
char c = monomial.charAt(x);
int countcoeff = 0;
int countvar = 0;
// check if negative.
if (c == minus)
{
isnegative = true;
x++;
}
// get the coefficient.
if (Character.isDigit(c))
{
while (Character.isDigit(c))
{
countcoeff++;
x++;
}
if (isnegative)
{
setCoeff(Integer.parseInt(monomial.substring(1, countcoeff)));
} else
{
setCoeff(Integer.parseInt(monomial.substring(0, countcoeff)));
}
}
// get the variable.
if (Character.isLetter(c))
{
char var = c;
while (Character.isLetter(var))
{
countvar++;
addpow++;
x++;
}
}
// get the power.
if (c == powsign)
{
countvar++;
x++;
while (Character.isDigit(c))
{
x++;
}
if (isnegative)
{
setPow(Integer.parseInt(monomial.substring(countcoeff+countvar+2, x)));
} else
{
setPow(Integer.parseInt(monomial.substring(countcoeff+countvar+1, x)));
}
pow += addpow;
}
}
if (isnegative)
{
stringBuilder.append(String.valueOf(minus));
}
stringBuilder.append(String.valueOf(coeff) + String.valueOf(var) + String.valueOf(powsign) + String.valueOf(pow));
mono = stringBuilder.toString();
monomials.set(i, mono);
}
for (int i = 0; i < monomials.size(); i++)
{
System.out.println(String.valueOf(monomials.get(i)));
}
} // End of method analyse().
} // End of class Monomial
You have a couple of loops which will never exit:
while (Character.isDigit(c))
{
countcoeff++;
x++;
}
How to find out Stuff like that?
If you use Eclipse, you can run your Code in Debug Mode, switch to the debug-perspective and click on the yellow Suspend-Symbol. That will suspend your Program, in the Debug-View you can see in which line the Thread is "hanging", if you click on it it will open the source-code.
If you don't use an IDE with that function, you can use the JDK-Tools: Use jps to find out the ID of your program:
C:\jdk\jdk8u45x64\jdk1.8.0_45\bin>jps
7216
5688 Jps
6248 Monomials
Then use jstack to print a stack trace of all running threads:
C:\jdk\jdk8u45x64\jdk1.8.0_45\bin>jstack 6248
[other threads omitted]
"main" #1 prio=5 os_prio=0 tid=0x000000000203e800 nid=0x1b2c runnable [0x000000000201e000]
java.lang.Thread.State: RUNNABLE
at Monomials.analyse(Monomials.java:77)
at Monomials.main(Monomials.java:10)
one of your loop is running infinitely. You should replace it with if condition.
while (Character.isDigit(c))
{
countcoeff++;
x++;
}
replace it with
if (Character.isDigit(c))
{
countcoeff++;
x++;
}
Or you could use break statement here.
As the others stated already
while (Character.isDigit(c))
is your problem.
But you have that two times not one time, so both are a problem. The 2nd isn't a real problem, because Character.isDigit and if (c == powsign) canĀ“t be both true at the same time, so the 2nd inifit loop never gets executed, which brings me to the next point: bugs.
In your code there are a tremendous amount of them :-D
Both for loops are running to far (<= .size() & <= .length()), replace <= with <.
Also, the x++ placed around in your code are wrong. x gets incremented automaticially and if you want to exit the loop early, use break; or use continue; if you want to jump to the next iteration early.

java Recursion row

i'm getting lost, could someone of you please help me?
i want my function "oddEvenRow" to check if the values in row index 0,2,4 are odd. if so return true, if not return false
this is the code i wrote :
public class Matrix
{
public static int temp=0;
public static boolean oddEvenRow (int[][]a, int r, int c, int count)
{
if(r>4&&count==12) {
temp=1;
return false;
}
if(a[r][c]%2==0) {
temp=1;
return false;
}
else {
count++;
if(c==3)
oddEvenRow(a,r+2,0,count);
else
oddEvenRow(a,r,c+1,count);
return true;
}
}
public static void main(String args[])
{
int r=0;
int c=0;
int count=0;
int[][]a=new int[5][4];
a[0][0]=1;
a[0][1]=3;
a[0][2]=7;
a[0][3]=15;
a[1][0]=4;
a[1][1]=15;
a[1][2]=2;
a[1][3]=9;
a[2][0]=11;
a[2][1]=21;
a[2][2]=1;
a[2][3]=45;
a[3][0]=8;
a[3][1]=15;
a[3][2]=8;
a[3][3]=12;
a[4][0]=7;
a[4][1]=3;
a[4][2]=25;
a[4][3]=21;
System.out.println(oddEvenRow(a,r,c,count));
}
}
[Looking at your code, i suspect you meant your question to say "if ALL values in rows 0,2, and 4 are odd..."]
Anyway, you're setting the short circuit variable 'temp' but never using it. Try adding a check to the top of your function...
if(temp == 1)
return false;
For me the part with count is redundant as you are checking all rows in r variable - after the last significant row (4th) the method will return. You do not need checking if there were 12 numbers checked.
What is more temp variable acts as return value in your code which you are actually returning with the method itself - also redundant.
I do not see the point in checking already defined number of values using recursion but if you need so consider the following:
public static boolean oddRow(int[][] a, int r, int c) {
//checking if we checked all rows
if (r > 4) {
return true;
}
//checking if all columns in row were checked and moving to r+2 row
if (c > 3) {
return oddRow(a, r + 2, 0);
}
//checking if current value is odd - if yes, keep checking the rest / if not, return false
return (a[r][c] % 2 == 0) ? oddRow(a, r, c + 1) : false;
}

How to avoid repetition in array filling

I have the next code and what I want to do is to check whether I have a value inside an array or not. The problem is, my code does the comparison just between the value I give as a parameter and the last value in the array, what I want to check is to see of I have the value and then return the boolean true, but my code just compare last value in the array. The code is here:
public boolean trueIdTienda(String s) {
boolean f = false;
for (int x = 0; x < lista.size(); x++) {
if (s.equals(ventas.getVenta(x).getIdTienda())) {
f = true;
} else {
f = false;
}
}
return f;
}
This part is not needed:
else {
f = false;
}
Since if one of them match it is a match, you don't need to set it back to true. Also you could return after a match, to speed the code up a bit (and more logical).
If you let the else part stay there, it will set the value back to false once it find a non-equal. Consider finding [1, 2] for 1 and you will see.
This is a classic search algorithm:
public boolean trueIdTienda(String s) {
for (int x = 0; x < lista.size(); x++) {
if (s.equals(ventas.getVenta(x).getIdTienda())){
return true;
}
}
return false;
}
Your function can be simplified to immediately return true if the value is found.
public boolean trueIdTienda(String s) {
for (int x = 0; x < lista.size(); x++) {
if (s.equals(ventas.getVenta(x).getIdTienda())) {
return true;
}
}
return false;
}
Maybe you can use a Collection. something like a Hash should help you
http://www.java2s.com/Tutorial/Java/0140__Collections/Createuniquelistsofitems.htm
The problem is that although you find that a value in the array is equal to the argument you set the boolean true and continue comparing with other values which return the boolean to false.
Final value of the boolean is the result of comparing with the last value, what solves the problem is to add break; after f=true;
Try to understand what caused your problem not simply using a correct code.

Categories

Resources