Recursion depth - tabs & dents in Java - java

I want to format my output of a Java program so that I can see "how deep" the recursion is. How to do it?
It is really important not to get lost in my recursion tree.
Example output (trivial recursion function for counting the nth number from 0):
This is the first recursive call. Input value: 3.
This is the second recursive call. Input value: 2.
This is the 3rd recursive call. Input value: 1.
Output value : 1.
This is again the second recursive call. Input value: 2.
Output value : 1 + 1.
This is again the first recursive call. Input value: 3.
Output value : 1 + 1 + 1.

You can use a variable (like level) that represents how deep you are. It starts at 1 and it increments at each recursive call.
public static void main(String[] args) {
function(3, 1);
}
public static String function(int input, int level) {
String tab = "";
for (int i = 0; i < level - 1; i++) {
tab += "\t";
}
System.out.println(tab + "This is the " + level + " recursive call. Input value: " + input);
if (input == 1) {
System.out.println(tab + "Output value: 1");
return "1";
}
String output = function(input - 1, level + 1);
System.out.println(tab + "This is again the " + level + " recursive call. Input value: " + input);
System.out.println(tab + "Output value: " + output + " + 1");
return output + " + 1";
}

Well, if you're using System.out.println, than you should be able to use "\tThis is the..." to indent the line on most java output windows. I don't understand if this is what you're asking for though.
If you don't know which recursion you're in, than you'd have to crawl Thread.currentThread().getStackTrace().
String s = "";
while(numRecursions --> 0) s += "\t";
System.out.println(s + "Something something something")
Again, if you don't have a numRecursions variable than you'd have to do something like this
int numRecursions = 0;
void a(){
int temp = ++ numRecursions;
String s = "";
while(temp --> 0) s += "\t";
System.out.println(s + "This is a recursion level");
//code
numRecursions--;
}

In your output function include a prefix string argument.
Every time you call your function pass in prefix + " ".
Example:
public void output(String prefix){
// Whenever you print, start with prefix
System.out.println(prefix + ...);
// When you call your recursive method
String childPrefix = prefix+" ";
output(childPrefix);
}

Related

How to tokenize the string with and without delimiter in single split

Assume i have a single string content as follows
Input:
FTX+AAA+++201707141009UTC'
FTX+BBB+++201707141009UTC'
FTX+CCC+++201707141009UTC?:??'
PISCO US LTS;?:V.D??'
SOUZA?:GB?:GB'
FTX+ZZZ+++201707141009UTC'
Expected Output:
Number of segments: 4
Input:
FTX+AAA+++201707141009UTC'
FTX+CCC+++201707141009UTC?:??'
PISCO US LTS;?:V.D??'
FTX+ZZZ+++201707141009UTC'
Expected Output:
Number of segments: 3
Basically i want to consider as same line when the delimiter ' comes with a question mark. The line delimiter is '
How to tokenize and get the count the segments in Java ???
Thanks in advance.
You can use a negative lookbehind in a regex:
String input = "FTX+AAA+++201707141009UTC'\n"
+ " FTX+BBB+++201707141009UTC'\n"
+ " FTX+CCC+++201707141009UTC?:??'\n"
+ " PISCO US LTS;?:V.D??' \n"
+ " SOUZA?:GB?:GB'\n"
+ " FTX+ZZZ+++201707141009UTC'";
String[] tokens = input.split("(?<!\\?)'\\s*");
System.out.println(tokens.length);
4
But, in the second example I would expect two segments, not three...
Another alternative to the above - but again demonstrating that the second example you post may be wrong because the third line ends with a ?' which, by your definition should not be a break.
public void test() {
test("FTX+AAA+++201707141009UTC'" +
"FTX+BBB+++201707141009UTC'" +
"FTX+CCC+++201707141009UTC?:??'" +
"PISCO US LTS;?:V.D??'" +
"SOUZA?:GB?:GB'" +
"FTX+ZZZ+++201707141009UTC'");
test("FTX+AAA+++201707141009UTC'" +
"FTX+CCC+++201707141009UTC?:??'" +
"PISCO US LTS;?:V.D??'" +
"FTX+ZZZ+++201707141009UTC'");
}
private void test(String s) {
String[] split = s.split("(?<!\\?)'");
System.out.println(split.length+"->"+Arrays.toString(split));
}
prints
4->[FTX+AAA+++201707141009UTC, FTX+BBB+++201707141009UTC, FTX+CCC+++201707141009UTC?:??'PISCO US LTS;?:V.D??'SOUZA?:GB?:GB, FTX+ZZZ+++201707141009UTC]
2->[FTX+AAA+++201707141009UTC, FTX+CCC+++201707141009UTC?:??'PISCO US LTS;?:V.D??'FTX+ZZZ+++201707141009UTC]
I think what he/she want is this:
String a = "FTX+AAA+++201707141009UTC'"
+ "FTX+BBB+++201707141009UTC'"
+ "FTX+CCC+++201707141009UTC?:??'"
+ "PISCO US LTS;?:V.D??' "
+ "SOUZA?:GB?:GB'"
+ "FTX+ZZZ+++201707141009UTC'";
String result[] = a.split("'");
List<String> stringList = new ArrayList<String>(Arrays.asList(result));
for (int i = 0; i < stringList.size(); i++) {
if (!stringList.get(i).startsWith("FTX") && i != 0) {
stringList.set(i-1, stringList.get(i-1) + stringList.get(i));
stringList.remove(i);
i--;
}
}
for (int j = 0; j < stringList.size(); j++) {
System.out.println(stringList.get(j));
}
FTX+AAA+++201707141009UTC
FTX+BBB+++201707141009UTC
FTX+CCC+++201707141009UTC?:??PISCO US LTS;?:V.D?? SOUZA?:GB?:GB
FTX+ZZZ+++201707141009UTC

Integer arguments being interpreted as String arguments in Java [duplicate]

This question already has answers here:
Java: sum of two integers being printed as concatenation of the two
(10 answers)
Closed 5 years ago.
Code:
class Foo
{
public static void main(String[] args)
{
int x[] = new int[5];
for(int i=0;i<5;i++)
x[i]=i*i;
for(int i=0;i<5;i++)
{
System.out.println("Value #" + i+1 + " = " + x[i]);
}
}
}
The Output:
tk#insomniac-tk:~$ java Foo
Value #01 = 0
Value #11 = 1
Value #21 = 4
Value #31 = 9
Value #41 = 16
So, what's going on here? Where am I messing up my java code? I mean why is it that in Java, the i+1 means literally i concat 1?
public class Foo
{
public static void main(String[] args)
{
int x[] = new int[5];
for(int i=0;i<5;i++)
x[i]=i*i;
for(int i=0;i<5;i++)
{
System.out.println("Value # " + (i+1) + " = " + x[i]);
}
}
}
try this
In Strings the + operator is used for concatenate, so because you did not specidy any parenthesis, your i and 1 are also concatentate, you need to use parenthesis to explicitly tell that they to be sum together :
for (int i = 0; i < 5; i++) {
System.out.println("Value #" + (i + 1) + " = " + x[i]);
}
To get :
Value #1 = 0
Value #2 = 1
Value #3 = 4
Value #4 = 9
Value #5 = 16
Next to that, another way using IntStream, which will do same :
IntStream.range(0, 5)
.mapToObj(i -> "Value #" + (i + 1) + " = " + (i * i))
.forEach(System.out::println);
The + means something like concat, if you want the expression to be evaluated put it into brackets
(i + 1) not i + 1
This line:
System.out.println("Value #" + i+1 + " = " + x[i]);
And in particular
"Value #" + i+1 + " = " + x[i]
Is syntactic sugar for the following code:
new StringBuffer().append("Value #")
.append(i)
.append(1)
.append(" = ")
.append(x[i])
.toString();
What you want is this:
"Value #" + (i+1) + " = " + x[i]
Which would translate to
new StringBuffer().append("Value #")
.append(i+1)
.append(" = ")
.append(x[i])
.toString();
Because in this case, Java append i to your String, then 1 to your String.
To evaluate the value first (and produce the result you are expecting here), you have to inform Java that you want to evaluate the value before it is appended, using parenthesis:
System.out.println("Value #" + (i+1) + " = " + x[i]);
Output
Value #1 = 0
Value #2 = 1
Value #3 = 4
Value #4 = 9
Value #5 = 16
The key reason the Java and C++ programs differ is because the operators used are different:
System.out.println("Value #" + i+1 + " = " + x[i]); // Java
cout << "Value # " << i + 1 << " = " << x[i] << endl; // C++
The + operator has a higher precedence and hence the addition is done before the overloaded << operator.
In the Java version it is all +s and so they are all evaluated left to right.
problem is in system.out.println("");,where all integers will concatinate into string when added using(+) with a string variable .Try different code for different operations with integer and string variables.
You cannot simply add an integer into a string. You must convert an integer to a string with Integer.toString(int),then add the returned value to the string.

How to only add something to a string if it doesn't contain it?

I am making a Lipogram program where any words with the banned letter are printed, however, the words are sometimes printed twice. How do I get it to not repeat the words?
Here is my code:
public String allWordsWith(char letter) {
String str = "";
String word = "";
s = s.replace(".", " ");
s = s.replace(",", " ");
s = s.replace("?", " ");
s = s.replace("!", " ");
s = " " + s + " ";
for (int i = 0; i <= s.lastIndexOf(letter); i++) {
if (s.charAt(i) == letter) {
if (str.contains(s.substring(s.lastIndexOf(" ", i), s.lastIndexOf(" ", i) + 1) + '\n') == true) {
} else {
word += s.substring(s.lastIndexOf(" ", i), s.indexOf(" ", i)) + '\n';
str += word;
}
}
}
return str;
}
Important clarification: Is the function run with the letter chosen as "o" on the string "hello hi hello howdy" meant to return "hello hello howdy" or "hello howdy". I.e., if the word appears twice, do you want to print it twice, or do you only want to print it once regardless of repetition?
If only once regardless of repetition, then you should be using a Set to store your data.
However, I think there's a chance you're instead dealing with an issue that when running the function with the letter chosen as "l" on that same string, "hello hi hello howdy", you are getting an output of "hello hello hello hello". Correct?
The issue here is that you are checking every letter and not testing each word. To fix this, I would use:
String[] words = s.split(" ");
to create an array of your words. Test each value in that array to see if it contains the given letter using:
if(words[index].contains(letter)){
str += " " + words[index];
}

Java 7 seemingly odd behavior with placement of empty string in debug message

I am noticing odd behavior, at least to me, in my program.
Incorrect output:
public static void main(String[] args)
{
while(count < 3)
{
System.out.println("Count: " + count);
System.out.println("" +(count*2)+1);
count++;
}
}
Yields the following print statements:
Count: 1
21
Count: 2
41
Whereas this program:
public static void main(String[] args)
{
while(count < 3)
{
System.out.println("Count: " + count);
System.out.println((count*2)+1 + "");
count++;
}
}
yields this output:
Count: 1
3
Count: 2
5
My question is does Java 7 do something special when you put the empty string, "", at the front of a arithmetic expression that it does not do when the empty string follows that arithmetic expression?
The + operator has two meanings.
number + number means addition; string + anything means string concatenation.
The + operator is left-associative.
Therefore, "" + a + b" is parsed as ("" + a) + b
You have a problem with brackets.
("" +(count*2)) + 1
and
(count*2 + 1) + ""
are not the same.

Java program that acts as an assembler (for a made up language): will not quit while loop

Basically, it is a two pass assembler and I am working on implementing entry points into a given assembly file. The format of the command is as follows:
Prog .ORIG
.ENT some,entry,point
some LD R0,entry
entry LD R1,point
point .FILL #42
.END some
The relevant part is the .ENT line. That is the line the assembler is getting hung up on.
The first pass takes care of handling .ENTs but it will not work for anything more than two arguments (that is, more than one comma). It does work for two operands and less, though. The code for the specific .ENT part is as follows:
String comma = ",";
String entry = "";
String[] tempEntryArray = new String[2];
int indexOfComma = read.indexOf(comma);
int startingIndex = 17;
int numOperands = 1;
while (indexOfComma != -1) {
if ((indexOfComma-startingIndex) == 0) {
return "An operand must precede the comma.";
}
if (numOperands > 4) {
return "The .ENT psuedo-op on line " + lineCounter
+ " has more than 4 operands.";
}
entry = overSubstring(read, startingIndex, indexOfComma);
if (entry.contains(" ")) {
return "The operand \"" + entry + "\" on line "
+ lineCounter + " has a space in it.";
}
if (entry.length() > 6) {
return "The operand \"" + entry + "\" on line "
+ lineCounter + " is longer than 6 characters.";
}
machineTables.externalSymbolTable.put(entry, tempEntryArray);
entry = read.substring(indexOfComma + 1);
startingIndex = indexOfComma + 1;
indexOfComma = entry.indexOf(comma);
if (indexOfComma != -1) {
indexOfComma += (startingIndex - 1);
}
numOperands++;
}
entry = overSubstring(read, startingIndex, read.length());
if (entry.contains(" ")) {
return "The operand \"" + entry + "\" on line "
+ lineCounter + " has a space in it.";
}
if (entry.length() > 6) {
return "The operand \"" + entry + "\" on line "
+ lineCounter + " is longer than 6 characters.";
}
machineTables.externalSymbolTable.put(entry, tempEntryArray);
read is a String containing one line of the input file.
overSubstring is a method that will perform similarly to substring but it will return a whitespace character if it reads a null string.
I am sorry for the huge block of code, and I know the error messages can be done a lot better, but for now I am concerned with this particular code hanging the assembler whenever there are more than two operands (more than one comma).
I would appreciate it very much if someone could help me with this problem.
Thanks.
I think that you're reading the same indexOfComma value infinitely. Instead of all that startingIndex and substring() business, just use String#indexOf(String, int) instead of String#indexOf(String) to properly skip the preceding indices you've already found.
Get indexOfComma consistently. Something like this:
int indexOfComma = -1;
int numOperands = 1;
while ((indexOfComma = read.indexOf(comma, indexOfComma+1)) != -1) {
// snip...
machineTables.externalSymbolTable.put(entry, tempEntryArray);
numOperands++;
}

Categories