The below code working without error but it not getting proper result for anagram. The if condition is return false for correct value.
import java.util.*;
public class Anagram{
public boolean solve(String s1, String s2){
if(s1.length() != s2.length()) return false;
String[] s11 = s1.split("");
String[] s12 = s2.split("");
Arrays.sort(s11);
System.out.println(Arrays.toString(s11));
Arrays.sort(s12);
System.out.println(Arrays.toString(s12));
for(int i = 0; i < s1.length(); i++){
if(s11[i] != s12[i])
System.out.println(s11[i]);
System.out.println(s12[i]);
return false;
}
return true;
}
public static void main(String[] args){
String s1 = "restful";
String s2 = "fluster";
Anagram v = new Anagram();
if(v.solve(s1, s2)){
System.out.println(s2 + " is anagram of the " + s1);
}else{
System.out.println("not an anagram");
}
}
}
Please let me know why it is not working
Ideally here no need to check individual character from both the Array
You can directly check both the Sorted Arrays are equals or not. Replace your for loop with the below code :
if(!Arrays.equals(s11, s12)){
return false ;
}
Also your code is not working because == is comparing the reference and not the value in Java
I have to ignore all special characters in the string.I have created a new string s1 including only alphanumerics characters.Then,made a reverse string s2 and then checked if they are pallindrome or not.
class Solution
{
public boolean isPalindrome(String s)
{
char c,ch;
String s1="";
String s2="";
s=s.trim();
s=s.toLowerCase();
if(s=="")
return true;
for(int i=0;i<s.length();i++)
{
c=s.charAt(i);
if(c>=97&&c<=122||c>=0&&c<=9)
s1=s1+c;
}
for(int j=s1.length()-1;j>=0;j--)
{
ch=s1.charAt(j);
s2=s2+ch;
}
if(s1.equals(s2))
return true;
else
return false;
}
}
String str = "# Test!##!#!#92432432";
String tmp = str.replaceAll("[^a-zA-Z0-9]", "");
System.out.println(tmp);
Prints
Test92432432
Ref:
How to ignore special characters and spaces in string?
As I understand, you are using c>=0&&c<=9 for checking c for digit. It is wrong, cause '0' == 48 and '9' == 57 and you have to use c>=48 && c<=57
And I want to give you some comments about your code:
String is an immutable object in java and a lot of string
concatenating - is a very bad practice. Please use StringBuilder.
You can use s.isEmpty() instead of s==""
Character class has static methods isDigit and isAlphabetic, whic are checks char for digit or alphabetic
If you will use StringBuilder, you can invert string just by stringBuilder.reverse() method
At the end of the method, you return true if s1.equals(s2) and false - overwise. You can just use return s1.equals(s2);
And you can iterating through the string with for (char c : s.toCharArray()) cycle
And the final code is
public static boolean isPalindrome(String s)
{
s=s.trim();
s=s.toLowerCase();
if(s.isEmpty())
return true;
StringBuilder sanitizedString = new StringBuilder();
for (char c : s.toCharArray()) {
if(Character.isAlphabetic(c) || Character.isDigit(c))
sanitizedString.append(c);
}
String s1 = sanitizedString.toString();
String s2 = sanitizedString.reverse().toString();
return s1.equals(s2)
}
And you can use regexp from #RR_IL answer for avoiding the cycle.
You can use something like this:
public static boolean isPalindrome(String s)
{
int i = 0;
int j = s.length() - 1;
while (i < j) {
if (s.charAt(i) != s.charAt(j))
return false;
i++;
j--;
}
return true;
}
Is there any helper method or utility that actually gives me union of two strings.
For instance, if i have two strings as below:
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
I'm looking for a solution which will take above two strings as input and outputs the result as below:
General syntax: s1.{method/utility}(s2);
output : Isabella,tom,hardy,victor,smith
First, there is no method or utility provided by JDK to address the problem so straight forward.
Second, just for this simple utility importing a 3rd party jar or dependency is not a wise choice.
In this case its always a wise choice to write your own method of purpose.
public static String mergeString(String s1, String s2) {
//check for null as the method doesnt fall in NPE
if(s1 == null || s2 == null) {
return null;
}
//split the given String to some list
List<String> s1List = Arrays.asList(s1.split(","));
List<String> s2List = Arrays.asList(s2.split(","));
//get a Set and add the list items to it. LinkedHashSet
//is used to maintain the given order.
Set<String> stringSet = new LinkedHashSet<>(s1List);
stringSet.addAll(s2List);
//Then join them using java 8 provided Utility
return String.join(",", stringSet);
}
NB: as you mentioned in the comments you may need this type of utility only once in your project. But despite, this logic should be separated from out of your business method. This will make your code more clean and readable.
You can use org.springframework.util.StringUtils
Add a maven dependency spring-core:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.8.RELEASE</version>
</dependency>
Use StringUtils:
public static void main(String[] args) {
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
String[] outputArr=StringUtils.mergeStringArrays(s1.split(","),s2.split(","));
String output=StringUtils.arrayToCommaDelimitedString(outputArr);
System.out.println(output);
}
Output:
Isabella,tom,hardy,victor,smith
public void unionString(String s1, String s2){
String[] s1Ar = s1.split(",");
String[] s2Ar = s2.split(",");
HashSet<String> set = new HashSet<String>();
for(int i=0;i<s1Ar.length;i++){
set.add(s1Ar[i]);
}
for(int i=0;i<s2Ar.length;i++){
set.add(s2Ar[i]);
}
Iterator<String> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
Here's a method that will do the union of two strings. You can also pass it a boolean flag to dictate case sensitivity.
public static String union (String s1, String s2, boolean caseInsensitive)
{
// if either string is null, union is the other string
if (s1 == null)
return s2;
if (s2 == null)
return s1;
// use linked set to keep ordering
Set<String> unique = new LinkedHashSet<>();
// put all words from string 1 into the set
for (String word : s1.split(","))
{
word = word.trim(); // remove surrounding space on word
if (caseInsensitive)
{
word = word.toLowerCase();
}
unique.add(word);
}
// put all words from string 2 into the set
for (String word : s2.split(","))
{
word = word.trim(); // remove surrounding space on word
if (caseInsensitive)
{
word = word.toLowerCase();
}
unique.add(word);
}
// get back the format of comma delimiter for the union
String ret = unique.toString().replaceAll("[\\[\\] ]", "");
return ret;
}
Usage:
public static void main(String args[])
{
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
String union = union(s1, s2, false);
System.out.println(union);
}
Outputs:
Isabella,tom,hardy,victor,smith
You Can Use LinkedHashSet which maintains the insertion Order to get desired output.Below is my code:
public class UnionJava {
static LinkedHashSet<String> hashSetString = new LinkedHashSet<>();
static String s1 = "Isabella,tom,hardy"; static String s2 = "Isabella,tom,hardy,victor,smith";
public static void main(String args[]){
String[] set1 = s1.split(","); String[] set2 = s2.split(",");
for(int i=0; i< set1.length;i++){
hashSetString.add(set1[i]);
}
for(int i=0;i<set2.length;i++){
hashSetString.add(set2[i]);
}
int j=0;
for(Iterator i = hashSetString.iterator(); i.hasNext();){
if(j==0){
System.out.print(i.next());
j++;
}else{
System.out.print(","+i.next());
}
}
}
}
A short version with no sanity checks using LinkedHashSet.
public void printUnion() {
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
Set<String>mySet = new LinkedHashSet<>();
mySet.addAll(Arrays.asList(s1.split(",")));
mySet.addAll(Arrays.asList(s2.split(",")));
mySet.stream().forEach(System.out::println);
}
With the java api, you might try :
public class StringTest {
private String string1 ="";
private String string2 ="";
private List<String> array1 = new ArrayList<String>();
private List<String> array2 = new ArrayList<String>();
private String[] stringa1;
private String[] stringa2;
private int output3 = 0;
private int output4 = 0;
public static void main(String[] args) {
new StringTest().startApp();
}
private void startApp() {
string1 = "Isabella,tom,hardy";
stringa1 = string1.split("\\s+"); //array to split
string2 = "Isabella,tom,hardy,victor,smith";
stringa2 = string2.split("\\s+");
for(int o = 0; o<stringa1.length; o++) {
array1.add(stringa1[o]); //adding to arraylist
}
for(int o = 0; o<stringa2.length; o++) {
array2.add(stringa2[o]);
}
for(int outP = 0; outP<array2.size()+array1.size(); outP++) {
for(output4 = 0; output4<array2.size(); output4++) { //iterating and removing double elements
for(output3 = 0; output3<array1.size(); output3++) {
if(array1.size() > array2.size() && array2.get(output4).equalsIgnoreCase(array1.get(output3))) {
array1.remove(array1.get(output3));
}
if(array1.size() < array2.size() && array2.get(output4).equalsIgnoreCase(array1.get(output3))) {
array2.remove(array2.get(output4));
}
}
}
}
array1.addAll(array2); //merging the lists
for(String outPres1 : array1) {
result += " " + outPres1;
}
System.out.println("This is the output: " + result);
}
String s1 = "Isabella,tom,hardy";
String s2 = "Isabella,tom,hardy,victor,smith";
Set<String> result = new TreeSet<String>();
result.addAll(Arrays.asList(s1.split((","))));
result.addAll(Arrays.asList(s2.split((","))));
System.out.println(result);
Well, someone's got to provide a streams solution:
Stream.of(s1, s2)
.flatMap(Pattern.compile(",")::splitAsStream)
.distinct()
.collect(Collectors.joining(","))
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();
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 );
}
}