string printing reference in java - java

I have this code where I am printing a string variable. The first output is showing what is expected but the second time it prints some unreadable output(I think its reference id). Please explain: Why does this happen?
public class Str3 {
public String frontBack(String str) {
char c[] = str.toCharArray();
char temp = c[0];
c[0] = c[c.length - 1];
c[c.length - 1] = temp;
return c.toString();
}
public static void main(String args[]) {
Str3 s = new Str3();
String s1 = new String("boy");
System.out.println(s1);
String s2 = s.frontBack("boy");
System.out.println(s2);
}
}
Output:
boy
[C#60aeb0

the frontToBack() method is calling toString() on a character array object char[] which is why you see the [C#60aebo. Instead of calling toString() return with new String(c); or String.valueOf(c)

Array types in Java do not override Object#toString(). In other words, array types inherit Object's implementation of toString() which is just
public String toString() {
return getClass().getName() + "#" + Integer.toHexString(hashCode());
}
which is the output you see
[C#60aeb0
If you want to see a representation of the contents of an array, use Arrays.toString(..).
In your case, you seem to want to switch the first and last characters and return the corresponding string. In that case, just create a new String instance by passing the char[] to the constructor.

You don't need to implement a custom class to do this. The functionality is already in java.
This question has already been answered # Reverse a string in Java
(duplicate thread)

use new String(c) to c.toString();
c.toString() c mean array of chars toString() print hash method
public class Str3 {
public String frontBack(String str) {
char c[] = str.toCharArray();
char temp = c[0];
c[0] = c[c.length - 1];
c[c.length - 1] = temp;
return new String(c);
}
public static void main(String args[]) {
Str3 s = new Str3();
String s1 = new String("boy");
System.out.println(s1);
String s2 = s.frontBack("boy");
System.out.println(s2);
} }

Related

Array values do not update

I am trying to use the string after I passed it through my cleanUp function. When I return the arguments it no longer keeps the same value.
My initial strings have punctuations.
I pass the strings to a method to clean up the punctuations.
I return the modified strings back to my main method.
I print out the modified string but my results have returned to the original value of the string.
public class test{
public static void main(String[] args){
String str1 = "this-is.first:sentence/.";
String str2 = "this=is.second:sentece.";
String[] arr = cleanUp(str1, str2);
for (String string : arr){
System.out.println("string after cleanup()" + string);
}
}
public static String[] cleanUp(String str1, String str2) {
String[] arr = {str1, str2};
for (String string : arr){
string = string.replaceAll("\\p{Punct}","");
System.out.println("string cleaned:" + string);
}
return new String[] {str1, str2};
}
}
Current Output:
string cleaned: this is first sentence
string cleaned: this is second sentece
string after cleanup(): this-is.first:sentence/.
string after cleanup(): this=is.second:sentece.
Expected Output:
string cleaned: this is first sentence
string cleaned: this is second sentece
string after cleanup(): this is first sentence
string after cleanup(): this is second sentece
You have two issues in your code which have to do with the fact that Java is pass-by-value.
You are re-assigning your local string variable in the loop, not what is inside the array. So string has the correct value, the string in array still has the old value.
Your output is build out of string1 and string2 which you did never update. Your updated content is supposed to be in the arr array you built using your loop. So you must either update the values based on the arrays content or return the arrays content or directly the array
Here is a fixed version:
public static String[] cleanUp(String str1, String str2) {
String[] arr = { str1, str2 };
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i].replaceAll("\\p{Punct}", "");
System.out.println("string cleaned:" + arr[i]);
}
return arr;
}
A Java String is immutable, and when you use the for-each loop it hides your iterator. Basically, your current code is almost correct but instead of using a for-each loop and locally modifying a temporary String, use a regular loop and modify the array you generate on the first line. Also, you should return that array instead of creating a new one. And, I assume you wanted to keep some white-space in your output. Something like,
public static String[] cleanUp(String str1, String str2) {
String[] arr = { str1, str2 };
for (int i = 0; i < arr.length; i++) {
arr[i] = arr[i].replaceAll("\\p{Punct}", " ").replaceAll("\\s+", " ");
System.out.println("string cleaned:" + arr[i]);
}
return arr;
}
Which I tested with your other code (and it returns)
string cleaned:this is first sentence
string cleaned:this is second sentece
string after cleanup()this is first sentence
string after cleanup()this is second sentece

Shuffle two Strings recursively to make another String

I'm trying to create a method shuffle (String stri, String str2, String str3) that returns a boolean and take two Strings and "shuffles" them to make a third String, but I'm trying to do it recursively, which is kind of tough for me to think about. I want to return true if str1 and str2can be shuffled and return false if they can't be shuffled.
For example, if str1 = "tv" and str2 = "aol", the method might return taovl.
I also plan to test the method out as well as create another helper method to make it more efficient, but that's easy.
import java.util.Scanner;
public class lab3{
public static void main(String[] args) {
String str;
System.out.print("Enter String: ");
Scanner sc = new Scanner(System.in);
str = sc.nextLine();
String res = revRec3(str);
System.out.println(res);
}
public static String revRec3(String str)
{
if (str.length() <= 1)
return str;
else{
String first = str.substring(0, str.length() / 3);
String second = str.substring(str.length() / 3, ((2 * str.length()) / 3));
String third = str.substring((2 * str.length()) / 3, str.length());
return revRec3(third)+revRec3(second)+revRec3(first);
}
}
}
try doing something like this. This Program splits a String into 3 pieces and then reverses them using recursion.
I solved this by simply creating three integer variables to go through the indices of all three strings and checking to see if a a letter at any index matches the same order of s3

How to increment a particular character in string (Java)

suppose i have a string s1 = "abcd";
output should be s1 = "abca";
I want to decrement/increment the last character in the string so that it matches the first character of the string .
Since String doesn't allow to modify the data
How can I achieve this.
Since, as you noted, String is immutable you will have to perform an assignment. I'd do a substring() and then concatenate the first letter. Something like
String s1 = "abcd";
s1 = s1.substring(0, s1.length() - 1) + s1.charAt(0);
System.out.println(s1);
Output is (as requested)
abca
JLS-4.2.1. Integral Types and Values does document that char is an integral type. That allows you to do something like
public static String modifyCharInString(String in, int index, int ammount) {
if (in == null || in.isEmpty() || index < 0 || index >= in.length()) {
return in;
}
StringBuilder sb = new StringBuilder(in);
sb.setCharAt(index, (char) (in.charAt(index) + ammount));
return sb.toString();
}
And then you an call it like
public static void main(String[] args) {
String s1 = "abcd";
s1 = modifyCharInString(s1, s1.length() - 1, -3);
System.out.println(s1);
}
Output is (again)
abca
For editing Strings you can use StringBuilder class. This allows you to get better performance, than using substring().
String oldString = "abcd";
StringBuilder sb = new StringBuilder(oldString);
sb.setCharAt(sb.length() - 1, sb.charAt(0));
String newString = sb.toString();

String permutation with recursion

I am a java beginner and trying to do a string permutation practice from java programming book. I am defining two method:
public static void displayPermutation(String s)
public static void displayPermutation(String s1, String s2)
The first method simply invokes displayPermutation(" ", s). The second method uses a loop to move a character from s2 to s1 and recursively invokes it with a new s1 and s2. The base case is that s2 is empty and prints s1 to the console.
Can anyone help me to find what is the problem of the following code?
Her's example:
public static void displayPermutation(String s) {
displayPermuatation("", s);
}
private static void displayPermuatation(String s1, String s2) {
//base case: when s2 is empty, print s1
if (s2.isEmpty()) {
System.out.println(s1);
}
else {
for (int i = 0; i < s2.length(); i++) {
//move a char from s1 to s2, and recursively invokes it with
//new s1 and s2
s1 = s1 + s2.charAt(i);
s2 = s2.substring(0, i) + s2.substring(i+1);
displayPermuatation(s1, s2);
}
}
}
if s = "abc",
it prints only:
abc
acb
it seems that in the first call of displayPermuatation("", "abc"), it does not finish the for loop....
any comments?
Thanks for all the comments below. I think the mistakes I made is because that passing object as argument to a method is actually passing the reference. it is not like primitive data (passing by value). When changing the object, it will affect following method call using that object.
Do not alter s1 and s2 in the loop, that causes the error. Simply pass those definitions as arguments to recursive function. Like this:
.
.
for (int i = 0; i < s2.length(); i++) {
displayPermuatation(s1 + s2.charAt(i), s2.substring(0, i) + s2.substring(i+1));
}
.
.
Problem with your code is that you are changing value of s1 and s2 in the loop which affects the following iterations in the loop, see the following code where I have fixed this issue.
public static void displayPermutation(String s) {
displayPermuatation("", s);
}
private static void displayPermuatation(String s1, String s2) {
// base case: when s2 is empty, print s1
if (s2.isEmpty()) {
System.out.println(s1);
} else {
for (int i = 0; i < s2.length(); i++) {
// move a char from s1 to s2, and recursively invokes it with
// new s1 and s2
displayPermuatation(s1 + s2.charAt(i), s2.substring(0, i) + s2.substring(i + 1));
}
}
}
Don't change the original values for s1, s2 in the loop:
private static void displayPermuatation(String s1, String s2) {
//base case: when s2 is empty, print s1
if (s2.isEmpty()) {
System.out.println(s1);
}
else {
for (int i = 0; i < s2.length(); i++) {
//move a char from s1 to s2, and recursively invokes it with
//new s1 and s2
string new_s1 = s1 + s2.charAt(i);
string new_s2 = s2.substring(0, i) + s2.substring(i+1);
displayPermuatation(new_s1 , new_s2 );
}
}

Compare strings in java and remove the part of string where they are identical

I have two strings with me:
s1="MICROSOFT"
s2="APPLESOFT"
I need to compare the strings and remove the duplicate part (always towards the end) from the second string. So I should get "MICROSOFT" and "APPLE" as output.
I have compared both the strings character by character.
String s1 = "MICROSOFT";
String s2 = "APPLESOFT";
for(int j=0; j<s1.length(); j++)
{
char c1 = s1.charAt(j);
char c2 = s2.charAt(j);
if(c1==c2)
System.out.println("Match found!!!");
else
System.out.println("No match found!");
}
It should check the strings and if the two strings have same characters until the end of string, then I need to remove that redundant part, SOFT in this case, from the second string. But I can't think of how to proceed from here.
There can be more duplicates...but we have to remove only those which are continuously identical. if i have APPWWSOFT and APPLESOFT, i should get APPLE again in the second string since we got LE different than WW in between
Can you guys please help me out here?
Search and read about Longest Common Subsequence, you can find efficient algorithms to find out the LCS of two input strings. After finding the LCS of the input strings, it is easy to manipulate the inputs. For example, in your case an LCS algorithm will find "SOFT" as the LCS of these two strings, then you might check whether the LCS is in the final part of the 2nd input and then remove it easily. I hope this idea helps.
An example LCS code in Java is here, try it: http://introcs.cs.princeton.edu/java/96optimization/LCS.java.html
Example scenario (pseudocode):
input1: "MISROSOFT";
input2: "APPLESOFT";
execute LCS(input1, input2);
store the result in lcs, now lcs = "SOFT";
iterate over the characters of input2,
if a character exists in lcs then remove it from input2.
As far as I understand, you want to remove any identical characters from the two strings. By identical I mean: same position and same character(code). I think the following linear complexity solution is the simplest:
StringBuilder sb1 = new StringBuilder();
StringBuilder sb2 = new StringBuilder(); //if you want to remove the identical char
//only from one string you don't need the 2nd sb
char c;
for(int i = 0; i<Math.min(s1.length,s2.length);i++){
if((c = s1.charAt(i)) != s2.charAt(i)){
sb1.append(c);
}
}
return sb1.toString();
Try this algo- Create characters sequences of your first string and find it in second string.
performance -
Average case = (s1.length()-1)sq
public class SeqFind {
public static String searchReplace(String s1,String s2) {
String s3;
boolean brk=false;
for(int j=s1.length();j>0&&!brk;j--){
for (int i = j-4; i > 0; i--) {
String string = s1.substring( i,j);
if(s2.contains(string)){
System.out.println(s2+" - "+string+" "+s2.replace( string,""));
brk=true;
break;
}
}
}
return s3;
}
public static void main(String[] args) {
String s1 = "MICROSOFT";
String s2 = "APPLESOFT";
String s3 = searchReplace(s1,s2);
}
}
Out put -
APPLESOFT - SOFT - APPLE
public class Match {
public static void main(String[] args)
{
String s1="MICROSOFT";
String s2="APPLESOFT";
String[] s=new String[10];
String s3;
int j=0,k=0;
for(int i=s2.length();i>0;i--)
{
s[j]=s2.substring(k,s2.length());
if(s1.contains(s[j]))
{
s3=s2.substring(0,j);
System.out.println(s1+""+s3);
System.exit(0);
}
else
{
System.out.println("");
}
j++;
k++;
}
}
}
I have edited the code you can give it an another try.
try this, not tested thou
String s1 = "MICROSOFT";
String s2 = "APPLESOFT";
String s3="";
for(int j=0; j<s1.length(); j++)
{
if(s1.charAt(j)==s2.charAt(j)){
s3+=s1.charAt(j);
}
}
System.out.println(s1.replace(s3, " ") + " \n"+ s2.replace(s3, " "));
You should rather use StringBuffer if you want your String to be modified..
And in this case, you can have one extra StringBuffer, in which you can keep on appending non-matching character: -
StringBuffer s1 = new StringBuffer("MICROSOFT");
StringBuffer s2 = new StringBuffer("APPLESOFT");
StringBuffer s3 = new StringBuffer();
for(int j=0; j<s1.length(); j++)
{
char c1 = s1.charAt(j);
char c2 = s2.charAt(j);
if(c1==c2) {
System.out.println("Match found!!!");
} else {
System.out.println("No match found!");
s3.append(c1);
}
}
s1 = s3;
System.out.println(s1); // Prints "MICRO"
I have solved my problem after racking some brains off. Please feel free to correct/improve/refine my code. The code not only works for "MICROSOFT" and "APPLESOFT" inputs, but also for inputs like "APPWWSOFT" and "APPLESOFT" (i needed to remove the continuous duplicates from the end - SOFT in both the above inputs). I'm in the learning stage and I'll appreciate any valuable inputs.
public class test
{
public static void main(String[] args)
{
String s1 = "MICROSOFT";
String s2 = "APPLESOFT";
int counter1=0;
int counter2=0;
String[] test = new String[100];
test[0]="";
for(int j=0; j<s1.length(); j++)
{
char c1 = s1.charAt(j);
char c2 = s2.charAt(j);
if(c1==c2)
{
if(counter1==counter2)
{
//System.out.println("Match found!!!");
test[0]=test[0]+c2;
counter2++;
//System.out.println("Counter 2: "+counter2);
}
else
test[0]="";
}
else
{
//System.out.print("No match found!");
//System.out.println("Counter 2: "+counter2);
counter2=counter1+1;
test[0]="";
}
counter1++;
//System.out.println("Counter 1: "+counter1);
}
System.out.println(test[0]);
System.out.println(s2.replaceAll(test[0]," "));
}
}

Categories