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

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.

Related

Tough Algorithm - Do not let the same character repeat for n positions

I wasn't able to figure this one out since I don't know how to calculate "inserting" an underscore. I included my attempt at solving this problem.
Given a string, do not let the same character repeat for n positions. If it does repeat, insert an underscore to push
it X positions down. The final output needed is just the total number of characters.
Example 1) Input "QQ",2 becomes "Q__Q", the return value is 4.
Example 2) Input "ABCA",2 becomes "ABCA" (no spaces needed), total characters is 4.
Example 3) Input "DEDEE", 1 becomes "DEDE_E", total chars is 6.
Example 4) Input "JKJK", 2 becomes "JK_JK", total characters is 5 (The toughest example).
import java.lang.Math;
import java.util.HashMap;
import java.util.ArrayList;
public class Spacer {
public static void main (String args[]) {
System.out.println("QQ,2 = " + spacey("QQ", 2) + ", expected 4");
System.out.println("ABCA,2 = " + spacey("ABCA",2) + ", expected 4");
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
System.out.println("JKJK,2 = " + spacey("JKJK", 2) + ", expected 5");
}
private static int spacey(String word, int spaces) {
// int shift = 0;
HashMap<Character, Integer> hm = new HashMap<>();
for (int i=0; i<word.length(); i++) {
char letter = word.charAt(i);
System.out.println(i + "=" + letter + " last saw " + hm.get(word.charAt(i)));
if (hm.get(letter) == null) {
hm.put(letter, i);
} else {
System.out.println(i + "-" + hm.get(letter) + "<=" + spaces);
if (i - hm.get(word.charAt(i)) <= spaces) {
// System.out.println("add " + (spaces + 1 - (i - hm.get(letter))));
// shift += (spaces + 1) - (i - hm.get(letter));
word = word.substring(0, i) + "_" + word.substring(i);
System.out.println(i + " word=" + word);
}
hm.put(letter, i); // update the hashmap with the last seen again
}
}
return word.length();
}
}
Your question is (mainly) about inserting underscores. A key insight that can help move forward is that the input and output strings are different, so it would be cleaner to treat them as such, using a StringBuilder for example. Additionally, it doesn't hurt at this stage to use temporary variables to capture concepts such as distance between characters. Leveraging these two ideas, you can have more self-explanatory code, for example:
public static String space(String input, int spaces) {
HashMap<Character, Integer> map = new HashMap<>();
StringBuilder result = new StringBuilder();
for( char symbol : input.toCharArray() ) {
int position = result.length();
int lastPosition = map.getOrDefault(symbol, position-spaces-1);
int distance = position - lastPosition -1;
for( int j = 0; j < Math.max( spaces - distance, 0) ; j++ ) {
result.append('_');
}
result.append(symbol);
map.put(symbol, result.length()-1);
}
return result.toString();
}
(and once this is mastered and digested, it's of course possible to in-line the temps)
The requirement doesn't ask you to display the constructed string so we need to only do calculations. The regex (.+)\1 will match any repetition of 1 or more chars and countPattern returns how many times that pattern was found.
public static void main(String[] args) {
System.out.println("QQ,2 = " + spacey("QQ", 2) + ", expected 4");
System.out.println("ABCA,2 = " + spacey("ABCA",2) + ", expected 4");
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
System.out.println("JKJK,2 = " + spacey("JKJK", 2) + ", expected 6"); //in becomes JK__JK, ie. 4 + 2x'_'
}
private static int spacey(String word, int spaces) {
if(spaces<0){
throw new IllegalArgumentException("should be positive value");
}
if(word==null){
return 0;
}
if(spaces==0){
return word.length();
}
final Pattern repeatedCharRegex = Pattern.compile("(.+)\\1");
final int repetitions = countPattern(word, repeatedCharRegex);
return word.length() + repetitions*spaces;
}
public static int countPattern(String references, Pattern referencePattern) {
Matcher matcher = referencePattern.matcher(references);
int count = 0;
while (matcher.find()){
count++;
}
return count;
}
First of all you have an error in one of your test cases. Assuming you want to reproduce the cases in the quoted challenge, you need a 1 as second argument to the call to spacey here:
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
// ^ ^
The formula to calculate the number of underscores to insert is:
previousindex + n + 1 - i
...where previousindex is the index at which the current letter occurred before, and i is the current index.
You can repeat an underscore with the .repeat string method. Don't forget to update i afterwards, so it keeps pointing to the currently processed character (which moved forward).
So your code could work like this:
import java.lang.Math;
import java.util.HashMap;
import java.util.ArrayList;
public class Spacer {
public static void main (String args[]) {
System.out.println("QQ,2 = " + spacey("QQ", 2) + ", expected 4");
System.out.println("ABCA,2 = " + spacey("ABCA",2) + ", expected 4");
System.out.println("DEDEE,1 = " + spacey("DEDEE", 1) + ", expected 6");
System.out.println("JKJK,2 = " + spacey("JKJK", 2) + ", expected 5");
}
private static int spacey(String word, int spaces) {
HashMap<Character, Integer> hm = new HashMap<>();
for (int i=0; i<word.length(); i++) {
char letter = word.charAt(i);
if (hm.get(letter) == null) {
hm.put(letter, i);
} else {
int underscores = hm.get(letter) + spaces + 1 - i;
if (underscores > 0) { // Need to add underscores
word = word.substring(0, i) + "_".repeat(underscores) + word.substring(i);
i += underscores; // update i so it still points to the current character
}
hm.put(letter, i);
}
}
return word.length();
}
}

why integer is added with string in System.out.println ? in java

String s = new String("5");
System.out.println(1 + 10 + s + 10 + 5);
output of the following function is 115105 how ?
"+" is left associative so
1 + 10 => 11(int)
11 + s => "115"(String)
"115" + 10 => "11510"(String) 10 is converted to String
"11510" + 5 = "115105"(String) 5 is converted to String
Your code effectively functions as integer summation as long as it's possible, because the evaluation process goes from left to right. Once the String is encountered, the function switches to concatenation.
1 + 10 + "5" + 10 + 5
= (1 + 10) + "5" + 10 + 5
= 11 + "5" + 10 + 5
= 115105
String s = new String("5");
System.out.println(1 + 10 + s + 10 + 5);
Since expressions are evaluated from left to rignt your code is same as
System.out.println((((1 + 10) + "5") + 10) + 5);
So first (1 + 10) is evaluated and since it is simple integer addition you are getting 11 so your code becomes
System.out.println(((11 + "5") + 10) + 5);
Now (11 + "5") is evaluated and since one of arguments is String, it is being concatenated and result will also be String. So 11 + "5" becomes "11"+"5" which gives us String "115".
So after that our code is same as
System.out.println(("115" + 10) + 5);
and again in ("115" + 10) one of arguments is String so we are getting "115"+"10" which gives us another String "11510".
So finally we are getting to the point where we have
System.out.println("11510" + 5);
which is same as
System.out.println("115105");
(1 + 10)and 10 and 5 are regarded as three strings in your code
Java casts the integers as a string when you include a string in the addition, it becomes concatenation. Try
import java.io.*;
import java.util.*;
import java.lang.*;
public class mainactivity {
public static void main(String a[]) {
String s = new String("5");
System.out.println((1 + 10) + s + (10 + 5));
}
}
This should output 11515.

Problems with while() loop [duplicate]

This question already has answers here:
Comparing two integer arrays in Java
(10 answers)
Closed 7 years ago.
The statement before the begining of while loop System.out.println("Value of i before loop = " + i); is not being printed and the value of i in the loop is not being printed starting from 1. Instead it starts printing from a random big int.
package main;
import java.util.Random;
public class Main {
public static void main(String args[]){
Random ran = new Random();
int[] in = {2,5,9};
int[] c_gen = new int[3];
int i = 0;
System.out.println("Value of i before loop = " + i);
while(!(c_gen.equals(in))){
c_gen[0] = ran.nextInt(10);
c_gen[1] = ran.nextInt(10);
c_gen[2] = ran.nextInt(10);
i++;
System.out.println(c_gen[0] + " " + c_gen[1] + " " + c_gen[2] + " .................." + i);
}
System.out.print("in = ");
for(int x : in)
System.out.print(x + " ");
System.out.print("\n" + "c_gen = ");
for(int x : c_gen)
System.out.print(x + " ");
System.out.println("\n" + "i = " + i);
}
}
You are directly comparing arrays resulting in an infinite loop. Those results are being printed but are going to be at the top of tons and tons of output. Fix your comparison.
Sotirios' intuition is correct - your bug is in the line while(!(c_gen.equals(in))). You can't compare arrays for equality using the .equals(...) method because "arrays inherit their equals-method from Object, [thus] an identity comparison will be performed for the inner arrays, which will fail, since a and b do not refer to the same arrays." (source). Thus because c_gen and in will always refer to different arrays (even if their contents are the same), your loop will go forever.
Try Arrays.equals(..) instead:
public static void main(String[] args) {
Random ran = new Random();
int[] in = {2,5,9};
int[] c_gen = new int[3];
int i = 0;
System.out.println("Value of i before loop = " + i);
while(!Arrays.equals(in, c_gen)){
c_gen[0] = ran.nextInt(10);
c_gen[1] = ran.nextInt(10);
c_gen[2] = ran.nextInt(10);
i++;
System.out.println(c_gen[0] + " " + c_gen[1] + " " + c_gen[2] + " .................." + i);
}
System.out.print("in = ");
for(int x : in)
System.out.print(x + " ");
System.out.print("\n" + "c_gen = ");
for(int x : c_gen)
System.out.print(x + " ");
System.out.println("\n" + "i = " + i);
}
This works (terminates in finite time) for me, with sample output:
Value of i before loop = 0
1 9 9 ..................1
5 4 1 ..................2
1 1 6 ..................3
1 3 6 ..................4
.... //Omitted because of space
6 5 8 ..................1028
2 5 9 ..................1029
in = 2 5 9
c_gen = 2 5 9
i = 1029
I get:
Value of i before loop = 0
2 2 1 ..................1
2 2 4 ..................2
...
Suggest you rebuild the project and try again.
As originally posted your code will not terminate because int[].equals(int[]) will not do what you expect.
You could try this though.
private static boolean equals(int[] a, int[] b) {
if (a == null && b == null) {
// Both null
return true;
}
if (a == null || b == null) {
// One null
return false;
}
if (a.length != b.length) {
// Differ in length.
return false;
}
for (int i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
// Mismatch
return false;
}
}
// Same.
return true;
}
public void test() {
Random ran = new Random();
int[] in = {2, 5, 9};
int[] c_gen = new int[3];
int i = 0;
System.out.println("Value of i before loop = " + i);
while (!equals(c_gen, in)) {
c_gen[0] = ran.nextInt(10);
c_gen[1] = ran.nextInt(10);
c_gen[2] = ran.nextInt(10);
i++;
System.out.println(c_gen[0] + " " + c_gen[1] + " " + c_gen[2] + " .................." + i);
}
System.out.print("in = ");
for (int x : in) {
System.out.print(x + " ");
}
System.out.print("\n" + "c_gen = ");
for (int x : c_gen) {
System.out.print(x + " ");
}
System.out.println("\n" + "i = " + i);
}

Recursion depth - tabs & dents in 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);
}

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.

Categories