Java Recursion Scope Variable - java

I was looking for a program to generate balanced parentheses for given n pairs. Link: https://leetcode.com/problems/generate-parentheses/
for the solution, I found that in the below code
public void P(List<String> list, int openB, int closeB, String output, int n) {
if (output.length() == 2 * n) {
list.add(output);
return;
}
if (openB < n) {
String op1 = output + "(";
// openB=openB + 1;
//P(list, openB, closeB, op1, n); using this is giving different output.
P(list, openB + 1, closeB, op1, n);
}
if (closeB < openB) {
String op2 = output + ")";
P(list, openB, closeB + 1, op2, n);
}
}
Here using
openB=openB+1; is giving a different result as compared to passing the value in the method itself

Well, when you pass openB + 1 as an argument, it doesn't change local openB variable. On the other hand, when you do openB = openB + 1 it does change its value, and, since we use it later in method (in closeB < openB branch), program could behave differently.

Related

Recursion in Java - print string permutations

I'm trying to write a method that prints all of the permutations of a string using recursion. For now, I have this code that works:
private static void printPermutations(String in, String out) {
if (in.length() == 0) System.out.println(out);
else {
for (int i = 0 ; i < in.length() ; i++) {
printPermutations(in.substring(0, i) + in.substring(i + 1), out + in.charAt(i));
}
}
}
It prints the right result, but I'm trying to solve it without using loops at all, including the one in line 4. Is it possible? If so, how would you solve it? Thank you!
I tried to add a third parameter called index and write index+1 inside the recursive call in line 5 but it didn't work. I think adding the third parameter is a good idea, I'm just not sure how to use it.
So I am not sure why you are trying to do that.. this is kind of the setup you would be doing for recursion, you need to not return void otherwise it's not really recursion. w3schools is a good resource.
public class Main {
public static void main(String[] args) {
int result = sum(10);
System.out.println(result);
}
public static int sum(int k) {
if (k > 0) {
return k + sum(k - 1);
} else {
return 0;
}
}
}
This would return something like
10 + sum(9)
10 + ( 9 + sum(8) )
10 + ( 9 + ( 8 + sum(7) ) )
...
10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + sum(0)
10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 + 0
I hope that kind of helps you put together what you need. You have to have a return so the Recursive method can see its previous call, it takes information then like a rubberband once it reaches a certain point it returns all of your iterations. Personally, I like loops more, easier to read and easier to code.
An implementation for what you are trying to do would be:
public class Main {
public static void main(String[] args) {
String result = Variations("test");
System.out.println(result);
}
public static String Variations(String k) {
if (k.length() > 0) {
return k + k.substring(0, k.lenth() - 1);
} else {
return "";
}
}
}
That would be the variation of what you are looking to do I believe.

Java method returns int that can't be compared to another int (Android Studio)

First off, these are ints, not Integers.
I want to get a variable from another class and compare it to a value, like so:
Log.v("xx", "" + boardAdap.getPieceNumber());
int pieceNumberInt = boardAdap.pieceNumber;
if (pieceNumberInt == 32) {
Log.v("xx", "int comparison worked");
}
int pieceNumberMethod = boardAdap.getPieceNumber();
if (pieceNumberMethod == 32) {
Log.v("xx", "method comparison worked");
}
So, I want to get the pieceNumber variable from the boardAdap class, and check if it is equal to 32. If it is, it prints the stuff in Log in the console.
The boardAdap method:
int pieceNumber;
int pieceNumberIncrement;
public int getPieceNumber() {
for (int i = 0; i < 64; i++) {
if (board.getPiece(Square.squareAt(i)).name() != "NONE") {
this.pieceNumberIncrement++;
}
}
this.pieceNumber = pieceNumberIncrement;
return pieceNumber;
}
This iterates through an enum called Square, and increments pieceNumberIncrement if the value is not "NONE".
However, when I run this, the output is:
32
int comparison worked
So, why does the second if condition fail, if getPieceNumber() returns an int? It also fails when I use an Integer wrapper, or convert pieceNumberMethod to a string and then to an Integer, and other methods.
Also, should I change getPieceNumber() to just update the pieceNumber instead, and reference only that?
Additionally, if pieceNumberMethod is used in a for loop like:
for (int i = 0; i < pieceNumberMethod; i++) {
}
The for loop will never stop.
Thanks!
You are basically calling getPieceNumber twice so in the second call the number changes.
int pieceNumberMethod = boardAdap.getPieceNumber();
Log.v("xx", "" + pieceNumberMethod);
int pieceNumberInt = boardAdap.pieceNumber;
if (pieceNumberInt == 32) {
Log.v("xx", "int comparison worked");
}
if (pieceNumberMethod == 32) {
Log.v("xx", "method comparison worked");
}
Try calling method once.Hope that works!
The problem is comparing the strings. You need equals("NONE")
String none = new String("NONE");
int count = 32;
System.out.println(count);
for (int i = 0; i < 64; i++) {
if (none != "NONE") {
count++;
}
}
System.out.println(count);
If you run this code it will print different values for "count" despite value of "none"

Why is post increment operator in a return statement act different from expected in Eclipse?

I see this post: In Java, how does a post increment operator act in a return statement?
And the conclusion is: a post increment/decrement happens immediately after the expression is evaluated. Not only does it happen before the return occurs - it happens before any later expressions are evaluated.
I tried the sample code in the post like below in Eclipse:
class myCounter {
private int _ix = 1;
public int ixAdd() {
return _ix++ + giveMeZero();
}
public int giveMeZero()
{
System.out.println(_ix);
return 0;
}
}
public class mytest {
public static void main(String[] args) {
myCounter m = new myCounter();
System.out.println(m.ixAdd());
}
}
and the result is:
2
1
It shows that _ix is incremented to 2 in giveMeZero() as expected. But ixAdd() is still returning 1.
Why is this happening? Isn't it against what In Java, how does a post increment operator act in a return statement? is all about?
Thanks,
Remember that the post increment operator evaluates to the original value before the increment is performed.
This means that e.g.
int a = i++;
is similar to doing:
int a = i;
i = i + 1;
That is, a receives the original value of i and after that, i is incremented.
When used in a return statement, there's no difference, it evaluates to the value before the increment.
return _ix++ + giveMeZero();
would be similar to:
int temp = _ix;
_ix = _ix + 1;
return temp + giveMeZero();
Think about the compiler evaluating each part of that return statement on at a time:
return _ix++ + giveMeZero();
Is the same as:
int tmp1 = _ix++;
int tmp2 = giveMeZero();
return tmp1 + tmp2;
So by the time giveMeZero is evaluated, _ix has already been incremented.
It is because _ix++ + giveMeZero(); first return then add 1 to _ix.
if you do ++_ix then it is OK
Note: ++ if first occur it means that firs add one and then do the operation, if occur after then it means that first do that operation then add one

Finding matching objects in Java

I'm currently trying to match 2 objects based on their values. Except, it's not a.a = a.a, but a.a = a.b and a.b = b.a. This means that overriding equals is an option but it's certainly not the right option.
While sorting these objects will make the matching time quicker, the population will be small so it is unnecessary. Also, compareTo isn't exactly right either for the same reason given for equals.
Do I simply make my own method in case? There will be 4 fields to match which is why I am not using an if statement up front.
public boolean isOpposite(Object other) {
return (this.a == other.b) ? true : false;
}
There is also the possibility that the object will implement/extend a base object to take on more fields and implement its own way of matching.
I'm considering using a LinkedList because I know it to be quicker for use than ArrayList, however I've also been considering Maps.
Edit: better explanation of objects
public class Obj {
public String a;
public String b;
public String c;
public double d;
}
The relationships are as follows:
Obj obj1, obj2;
obj1.a == obj2.b //.equals for String of course
obj1.b == obj2.a
obj1.c == obj2.c
obj1.d == obj2.d * -1
Overriding the equals or compareTo is not the right way to go, as you've mentioned. Because there is an assumption that both methods should be transitive, i.e. A eq B and B eq C => A eq C but it doesn't hold for the "opposite" objects. It's good to know, because you can't define a equivalence class and partition it into subsets, but you need to find all the pairs (depending on your use case).
Not sure, what is your goal. If you have some containers with such objects and you need to find all pairs that suffice the condition, then I am afraid you'd need to do n^2 comparisons.
I'll probably create two hash sets, one with the originals and second with the opposites and ask if the second hash set contains the opposite of each member of original hash set.
I've done some testing and determined that the cleanest way I knew how to implement this was with using ArrayList<Obj>.
This was my implementation:
public static List<ObjGroup> getNewSampleGroup(int size) {
List<ObjGroup> sampleGroup = new ArrayList<ObjGroup>();
sampleGroup.add(new ObjGroup((generateNumbers(size, 1)))); //Positives
sampleGroup.add(new ObjGroup((generateNumbers(size, -1)))); //Negatives
return sampleGroup;
}
private static List<Obj> generateNumbers(int size, int x) {
List<Obj> sampleGroup = new ArrayList<Obj>();
for (int i = 0; i < size; i ++) {
Random rand = new Random();
String randC;
String randA;
String randB;
double randD;
if (x == 1) {
randD = rand.nextInt((maxP - minP + 1) + minP);
randA = "aval";// + String.valueOf(rand.nextInt((max - min + 1) + min));
randB = "bval";// + String.valueOf(rand.nextInt((max - min + 1) + min));
randC = "cval";// + String.valueOf(rand.nextInt((max - min + 1) + min));
} else {
randD = rand.nextInt((maxP - minP + 1) + minP) * -1;
randA = "bval";// + String.valueOf(rand.nextInt((max - min + 1) + min));
randB = "aval";// + String.valueOf(rand.nextInt((max - min + 1) + min));
randC = "cval";// + String.valueOf(rand.nextInt((max - min + 1) + min));
}
sampleGroup.add(new Obj(randA, randB, randC, randD));
}
return sampleGroup;
}
public List<ObjGroup> findMatches(List<ObjGroup> unmatchedList) {
List<Obj> pivotPos = unmatchedList.get(0).getObjs(); //First grouping are positives
List<Obj> pivotNeg = unmatchedList.get(1).getObjs(); //Second grouping are negatives
List<ObjGroup> matchedList = new ArrayList<ObjGroup>();
long iterations = 0;
Collections.sort(pivotPos);
Collections.sort(pivotNeg, Collections.reverseOrder());
for (Iterator<Obj> iteratorPos = pivotPos.iterator(); iteratorPos.hasNext();) {
final Obj focus = iteratorPos.next();
iteratorPos.remove(); //Remove this once pulled as you won't match it again.
for (Iterator<Obj> iteratorNeg = pivotNeg.iterator(); iteratorNeg.hasNext();) {
final Obj candidate = iteratorNeg.next();
if (compare(focus, candidate)) {
matchedList.add(new ObjGroup(new ArrayList<Obj>() {
{
add(focus);
add(candidate);
}
}));
iteratorNeg.remove(); //Remove this once matched as you won't match it again.
break;
}
iterations ++;
}
iterations ++;
}
return matchedList;
}
I ran this against a sample size of 4,000,000 psuedo random Obj objects. This was my output:
Starting matching test.
18481512007 iterations.
3979042 matched objects.
10479 unmatched objects.
Processing time: 44 minutes.
There were 1989521 number of matches found.
Closing matching test.

Using mutual recursion to do a binary comparison of two files; would prefer to use one method, calling itself. How?

I've made a crossword (and similar) puzzle helper, which enables searching a dictionary for matches to a pattern such as pa??ern, pa*, pa??ern*, etc., where ? and * have the same meaning as wildcards in Windows (? matches any letter; * matches any number of letters [including 0]).
I found two text dictionaries online, one with 108,000+ words, the other with 80,000+. I assumed that the smaller would be a subset of the larger. Not even close.
So I wrote a Java program to compare and to print any word that is in one dictionary but not in the other. (Turned out there were 24,000+ words in the smaller than in the larger; 52,000+ in larger but not in smaller. So I now, via another program, have a dictionary with 132,000+ words.)
I used mutual recursion to accomplish this:
-When current words match, continue; nothing to print here.
-When current word from dictionary A is "<" than current word in B, then...
* print and read A until finding word ">=" current word in B.
--If '=', they match; continue without printing.
--If '>', then reverse the process:
* print and read B until finding word ">=" current word in A.
...
This is all there is to the logic. I really like recursion because it's how we think, though it's often very hard to get those thoughts into code.
And some things about the nature of programmatic recursion are very hard.
In particular, I had to use "dual" methods: one for reading A until >= B; one for reading B until >= A.
I tried to make one routine that would call itself in the same way the different routines call each other, as described above in pseudocode.
I'm asking for someone to show me how to use ONE method to call itself to accomplish the goal.
Here's the code that works but is inefficient, as described:
package filecomparison;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
public class ShorterBinaryCompare {
static int kta = 0, exa = 0, ktb = 0, exb = 0;
static Scanner sca, scb;
static String reca, recb;
static Path a = Paths.get("C:\\newdic.txt");
static Path b = Paths.get("C:\\WordHelp.dick");
private static int read_a_untilGE_b(){
while(sca.hasNext()){
if(reca.equals(recb)) return 0; // 0 => a = b
if(reca.compareTo(recb) > 0) break; // a > b
System.out.println(reca); exa++; kta++;
reca = sca.next();
}
read_b_untilGE_a();
return 0;
}
private static int read_b_untilGE_a(){
while(scb.hasNext()){
if(recb.equals(reca)) return 0; // a = b
if(recb.compareTo(reca) > 0) break; // b > a
System.out.println("\t\t" + recb); exb++; ktb++;
recb = scb.next();
}
read_a_untilGE_b();
return 0;
}
private static void drain(String msg, Scanner sc){
int k = 0;
System.out.println("\n\nDraining " + msg);
String s;
while(sc.hasNext()){
s = sc.next();
System.out.println(s);
++k;
}
System.out.println("\nExtras at end: " + k);
}
public static void main(String[] args) throws IOException {
System.out.println("Compare:\n" + a + " vs. \n" + b + "\n");
sca = new Scanner(a); scb = new Scanner(b);
while(sca.hasNext() && scb.hasNext()){
reca = sca.next(); kta++;
recb = scb.next(); ktb++;
int compareResult = reca.compareTo(recb);
if( compareResult < 0) read_a_untilGE_b(); // a < b
else if(compareResult > 0) read_b_untilGE_a() ; // a > b
// mutually-recursive read...untils make a = b at this point
}
System.out.println("\n\nRecords in " + a.toString() + ": " + kta);
System.out.println("Extras in " + a.toString() + ": " + exa);
System.out.println("Records in " + b.toString() + ": " + ktb);
System.out.println("Extras in " + b.toString() + ": " + exb);
if(sca.hasNext()){ drain(a.toFile().toString(), sca); }
if(scb.hasNext()){ drain(b.toFile().toString(), scb); }
}
}
Here's the last version I tried of one method calling itself. It worked as long as it was the "left" file with the extra words, but when it changed so that the "right" file had the extras, it didn't take long to get stack overflow. Maybe I'm closer than I thought; but I'm out of gas for the day.
Can you modify the method below, which calls itself, to do what mutual recursion does in the code above?
private static int read_untilGE_(Scanner a, Scanner b){
String sa, sb;
if(b.hasNext())
sb = b.next();
else
return -1;
System.out.println("Extra in " + a.toString());
while(sca.hasNext()){
sa = sca.next();
if(sa.equals(sb)) return 0; // a = b
if(sa.compareTo(sb) > 0) break; // a > b
System.out.println(sa); exb++; ktb++;
}
read_untilGE_(b, a);
return 0;
}
You got off to the right start by passing your two Scanners as parameters to your method, so that you call your method recursively by switching the parameters. Then you erred by using a Scanner (sca) that wasn't one of the parameters.
Thanks to #ajb's quick response and a good night's (... well, a few hours') sleep, I got exactly what I wanted. The fix wasn't quite as simple as changing Scanner sca to a, but it was exactly the problem that I failed to notice.
And I failed to notice it because of sloppy coding. I had too many global variables, especially sca and scb. Had they been local to main, I'd've caught the problem last night.
Here's the method that calls itself. The '--------------------' lines are the changes relative to the error in logic that ajb pointed out.
private static int read_untilGE_(Scanner a, String sa, long ma,
Scanner b, String sb, long mb){
String indent;
boolean shouldPrint;
if (ma == mapa){indent = inda; shouldPrint = showa;}
else {indent = indb; shouldPrint = showb;}
if(shouldPrint) System.out.println(indent + sa); // --------------------
while(a.hasNext()){ // --------------------
sa = a.next(); // --------------------
if(sa.equals(sb)) return 0; // a = b
if(sa.compareTo(sb) > 0) break; // a > b
if(shouldPrint) System.out.println(indent + sa);
}
read_untilGE_(b, sb, mb, a, sa, ma);
return 0;
}
And here's the rest of the program:
package filecomparison;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Scanner;
public class BinaryCompare {
static long mapa, mapb;
static String inda, indb;
static Boolean showa = true, showb = true;
private static void drain(String msg, Scanner sc){
int k = 0;
System.out.println("\n\nDraining " + msg);
String s;
while(sc.hasNext()){
s = sc.next();
System.out.println(s);
++k;
}
System.out.println("\nExtras at end: " + k);
}
public static void main(String[] args) throws IOException {
Scanner sca, scb;
String reca, recb;
Path a = Paths.get("C:\\newdic.txt");
Path b = Paths.get("C:\\WordHelp.dick");
sca = new Scanner(a); scb = new Scanner(b);
mapa = a.hashCode( ); mapb = b.hashCode();
inda = ""; indb = "\t\t\t";
System.out.println("Extra words in:\n" + inda + " " + a + "\n" + indb + b );
while(sca.hasNext() && scb.hasNext()){
reca = sca.next();
recb = scb.next();
int compareResult = reca.compareTo(recb);
if( compareResult < 0) read_untilGE_(sca, reca, mapa, scb, recb, mapb); // a < b
else if(compareResult > 0) read_untilGE_(scb, recb, mapb, sca, reca, mapa); // a > b
// recursion makes a = b at this point
}
if(sca.hasNext())drain(a.toFile().toString(), sca);
if(scb.hasNext())drain(b.toFile().toString(), scb);
sca.close(); scb.close();
} // end main
}

Categories

Resources