I am new here and I am somehow stuck.
I created an recursive algorithm that uses an global variable for remembering the Position he made the recursive call and I am trying to get rid of this variable as for me it seems to be not a good solution.
Is there any chance to get rid of this global variable? I cannot adjust the method-head so therefore the Interface of the method is fixed.
Here you can see my Code:
static int pos = -1;
static boolean writeInfix(char[] expr) {
boolean result;
pos++;
int printpos = pos;
if(expr[pos]=='+'||expr[pos]=='-'||expr[pos]=='/'||expr[pos]=='*'){
System.out.print("(");
writeInfix(expr);
System.out.print(expr[printpos]);
result = writeInfix(expr);
System.out.print(")");
return result;
}else if(expr[pos] >= 'a' && expr[pos] <= 'z'){
System.out.print(expr[pos]);
return true;
}else{
return false;
}
}
Thank you for your help :)
You can add a new auxiliary method, where you control its variables, and let writeInfix(char[]) be only a wrapper, that does nothing but calling the "real" method.
In this new method, pos is an arument.
This also ensures you can call your API method (writeInfix) twice (independently) without worrying from the side effects (pos is initialized with wrong value after first call).
You should be able to write another method with the position as additional argument:
private static boolean writeInfix(char[] expr, int pos) {
boolean result;
int printpos = pos;
if(expr[pos]=='+'||expr[pos]=='-'||expr[pos]=='/'||expr[pos]=='*'){
System.out.print("(");
writeInfix(expr);
System.out.print(expr[printpos]);
result = writeInfix(expr, pos + 1);
System.out.print(")");
return result;
}else if(expr[pos] >= 'a' && expr[pos] <= 'z'){
System.out.print(expr[pos]);
return true;
}else{
return false;
}
}
and in the method you already have, you just need to call
static boolean writeInfix(char[] expr) {
return writeInfix(expr, -1);
}
You can add pos as an argument to the writeInfix function.
static boolean writeInfix(char[] expr, int pos);
Whereever you are returning false, return -1. Whereever you are returning true, return the current pos value.
Related
I made a function that's meant to count the number of specific chars in a function recursively.
public static int countCharInString(String s, char c)
{
return countCharInString(s, c, 0);
}
public static int countCharInString(String s, char c, int index)
{
if(index==s.length())
{
return 0;
}
if(s.charAt(index) == c)
{
return 1 + countCharInString(s, c, index+1);
}
if(s.charAt(index)!=c)
{
return countCharInString(s, c, index+1);
}
}
How can I put a return statement at the end of the function that'll return the whole number I "counted" inside the function?
You don't need an extra return statement at the end of the method, the error you're getting is because the compiler isn't convinced that you've got all cases covered.
The easiest fix for this is to simply replace your second comparison against c with else. Either the character is equal to c or it isn't, you don't need a separate check.
e.g.
public static int countCharInString(String s, char c, int index) {
if (index == s.length()) {
return 0;
}
if (s.charAt(index) == c) {
return 1 + countCharInString(s, c, index + 1);
} else {
return countCharInString(s, c, index + 1);
}
}
I would use a for Loop, If the recursion is needed, Check If
Index+1 > s.length()
If this is the Case the recursion should return
You need to have a parameter to keep track of your running total. Add a parameter to your function which you'll increment each time you find the character. Then return that number instead of returning 0
Using recursion here does not make sense to me. The number of characters in a string is going to be `s.length()'.
However, since this is your requirement - I believe you want the count of some character - I recognized this as a classic 're-invent' the wheel program. While I dislike these, the important thing here is to understand what is happening.
Firstly, you don't need a variable for index... because you always set it to 0. So just use 0.
Secondly, let's use substring so we don't have to convert to chars and deal with character/String comparisons etc.
public static int countCharInString(String s, String c) {
// This will only happen when the string is empty to begin with, our we're done with recursion. Since we add this to another number in recursion - it works for our purpose
if (s.length() == 0) {
return 0;
}
// If we have a match, increment add add to our recursive sum
if ((s.substring(0, 1).equals(c))) {
return 1 + countCharInString(s.substring(1), c);
}
// do the final return and invoke recursion
return countCharInString(s.substring(1), c);
}
I am implementing a method to traverse a trie (more specifically, I am trying to count the number of leaf nodes. The edges going into these leaf nodes all have a terminator symbol '#').
I am using Java and am getting an error when using this method:
public int traverse(Node n){
for(int i=0; i<n.getNumEdges(); i++){
if(n.getEdgeChar(i) == '#'){
return 1;
}
else{
return traverse((n.getEdge(i)).getNode());
}
}
}
I do understand why I'm getting this error, but how do I get around it? Initially, I thought it best to pass noLeaves as a parameter, but after doing some research I found that the above code is considered better practice. I just don't know how to get around this compiler error. Any help would be appreciated!
There may be a case when n.getNumEdges() equals to 0 and the for statement won't execute. You should return a default value
return 0;
or throw an exception if such behaviour is considered illegal:
throw new IllegalArgumentException("There are no edges in the node!");
I am guessing a bit here, but I think the following is what you intended?
public int traverse(Node n){
int numOfLeaves = 0;
for (int i=0; i<n.getNumEdges(); i++) {
if(n.getEdgeChar(i) == '#') { // leaf
numOfLeaves += 1;
}
else {
numOfLeaves += traverse((n.getEdge(i)).getNode());
}
}
return numOfLeaves;
}
This will sum the results of the recursive calls for all edges and return the sum. # is assumed to indicate a leaf and will count as 1 in the sum rather than doing a recursive call.
When you declare your function returning any value(in your case int), it must return any integer by the end of code. In your method, it is possible that function may not return anything the node is empty or null.
To rectify the error, do following changes to your code
public int traverse(Node n){
int returnValue=-1;
for(int i=0; i<n.getNumEdges(); i++){
if(n.getEdgeChar(i) == '#'){
returnValue=1;
break;
/*return 1;*/
}
else{
returnValue=traverse((n.getEdge(i)).getNode());
break;
/*return */
}
}
return returnValue;
}
I want to know how to tell if an int has been changed (during the program).
Like with an if statement.
int i = 2;
int a = 1;
while(1 < 2) {
if(i % 100 == 0) i++;
}
if(i //Then checks if it changed) {
System.out.println("Changed :D");
}
Is there a way to tell if the variable i is changed DURING the program?
Since this is Java, are these variables data members of a class? In that case give them private access and provide getters and setters. Your setter can notify you if you so desire.
int i = 0;
boolean valueChanged = false;
while(some good condition) {
if (i % 100 == 0) {
i++;
valueChanged = true;
}
}
if(valueChanged) {
System.out.println("Changed :D");
}
// Your int variable
int i = 0;
// A scratch variable
int prev_value_of_i = i;
// Call this code to check whether i has changed since last call
if(i != prev_value_of_i) {
System.out.println("Changed :D");
prev_value_of_i = i;
}
Keep track of the original value of i in a separate variable and compare i to that?
This seems redundant, since the programmer should know when and where values are stored. If you don't, maybe step through with a debugger? #shoover's answer is the most flexible, handling however many unexpected times you might change the value without requiring adding lines of code inside your infinite loop.
class TalkativeInt{
private int x;
TalkativeInteger(int x){
this.x = x;
}
public void set(int a){
System.out.println("Changed!! "+x+" to "+a);
x = a;
}
public int get(){
//System.out.println("Accessed - that tickles");
return x;
}
}
I wrote this recursive method to find an integer in an integer array but it's not working. I tried debugging it but I don't know what the problem could be.
Here's the code
public static String inList(int[] primes,int a){
int index = -9;
if(primes.length>1){
index = primes.length/2;
}else{
if(primes[0] == a){
return "True";
}else{
return "False";
}
}
if(primes[index] == a){
return "True";
}
if(primes[index] > a){
inList(Arrays.copyOfRange(primes, 0, index),a);
}
if(primes[index]<a){
inList(Arrays.copyOfRange(primes, index, primes.length),a);
}
//shouldn't even get to this point, but eclipse insisted I needed another return
//statement
return "Whyyyyy?";
}
you have forgot to add return
did you sort your array?
if(primes[index] > a){
return inList(Arrays.copyOfRange(primes, 0, index),a);
}
if(primes[index]<a){
return inList(Arrays.copyOfRange(primes, index, primes.length),a);
}
Just use Arrays.binarySearch(). As you will see from its different prototypes, it will return a negative value if and only if the value you are looking for in the array is not there.
Recursive function to find something in an array would be:
public static String inList(int[] primes,int index, int a) {
/* two breaking conditions for recursion: end of array or number found */
if(index >= primes.length)
return "False";
if(primes[index] == a)
return "True";
/* recursion */
return inList(primes, ++index, a);
}
You can call above method with index = 0 ex. inList(primes, 0, a). This will be much slower than non-recursive find method.
Here's what I'm trying to accomplish with this program: a recursive method that checks if the number of instances of a substring matches a specified amount of instances, returning a boolean.
Here's the issue I'm having with this particular recursive method: I'd like to be able to move the counter inside the recursive method body, however, I ran into the issue that the counter resets at each recursive call when it is in the method body. The only way I have been able to make it work is through the use of a static counter variable declared outside of the function body. Is there any other technique I can marshall in order to be able to situate the counter of the method in the method body so that this method may act as a "black box"?
Thanks for any advice or insights you can provide.
public class strCopies {
//count instances of part and whole equality
static int count = 0;
public static boolean copies(String whole, String part, int check)
{
//check if current string length is valid
if(whole.length() < part.length())
{
//check if check parameter equals part instances
if(count == check)
{
return true;
}
else
{
return false;
}
}
//check if current string value is an instance of part
if(whole.substring(0, 3).equals(part))
{
count++;
}
//recursive call
return copies(whole.substring(1), part, check);
}
public static void main(String[] args)
{
System.out.println(copies("dogcatdog", "cat", 2));
}
}
You are almost there: you should change the meaning of the check variable to the remaining number of matches, rather than the original number requested. Then you can rewrite the method without keeping an additional count at all, as follows:
public static boolean copies(String whole, String part, int check)
{
//check if current string length is valid
if(whole.length() < part.length())
{
//check if check parameter equals part instances
if(check == 0)
{
return true;
}
else
{
return false;
}
}
//check if current string value is an instance of part
if(whole.substring(0, 3).equals(part))
{
check--;
}
return return copies(whole.substring(1), part, check);
}
You can pass the count as an argument to the recursive function, this way it will not be "reset" when the method is called.
public static boolean copies(String whole, String part, int check, int count)
{
//check if current string length is valid
if(whole.length() < part.length())
{
//check if check parameter equals part instances
if(count == check)
{
return true;
}
else
{
return false;
}
}
//check if current string value is an instance of part
if(whole.substring(0, 3).equals(part))
{
count++;
}
//recursive call
return copies(whole.substring(1), part, check, count);
}
public int countRecursive(String whole, String part){
if(whole.length() < part.length()) return 0;
if(part.length()==0) return -1; // ints can't express "Infinity"
// maybe you want to return -1 only if whole is not null, and something else if it is.
int count = 0;
if(whole.substring(0, part.length()).equals(part))
count = 1;
return countRecursive(whole.substring(1), part) + count;
}
public boolean count(String whole, String part, int check){
return countRecursive(whole, part) == check;
}
Note that this does away with the counter at the expense of creating a whole bunch of strings for each state. (You replace a single int with the length of each string given.) But then again, if you want performance then you shouldn't be using recursion for something like this. A simple for loop would do much nicer.
You could add the counter to the method parameters as follows:
public class strCopies {
public static boolean copies(String whole, String pargs, int check){
return copies(whole, pargs, check, 0);
}
public static boolean copies(String whole, String part, int check, int count)
{
//check if current string length is valid
if(whole.length() < part.length()) {
//check if check parameter equals part instances
if(count == check) {
return true;
}
else {
return false;
}
}
//check if current string value is an instance of part
if(whole.substring(0, 3).equals(part)) {
count++;
}
//recursive call
return copies(whole.substring(1), part, check, count);
}
public static void main(String[] args) {
System.out.println(copies("dogcatdog", "dog", 2));
}
}
The simple version:
Create a class that contain the counter.
Initialize it on your main.
Pass its reference to the function.
Another idea:
Create a singleton class with a static counter and your function X.
Inside its constructor add one to its counter and call function X.
Then instead of running your function like you did before, "create" that class, thus increasing the counter and calling the function.
The neat thing is you can inherit that class and redefine X to whatever you choose at a latter stage, so you get this general class that counts on each activation of a function.
Not sure what is your recursive method doing. However, to maintain a counter, you can pass it as an argument to your recursive method.
public boolean copies(String whole, String part, int check, int count) {
// your code here....
if(whole.substring(0, 3).equals(part))
{
count++;
}
//recursive call
return copies(whole.substring(1), part, check, count);
}
When you make first call to your copies method, you'll need to pass 0 to your count.