Odd character out given two strings - java

Beginner here -
I need to find the odd character out in a set of two strings. Everything compiles but when it goes to print out the odd character, it prints out the characters of the longer string..Does anyone know how i can fix it?
thanks
public class odd
{
public static void main(String[] args)
{
String str1;
String str2;
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter 2 words:");
str1 = keyboard.nextLine();
str2 = keyboard.nextLine();
int n1 = str1.length();
int n2 = str2.length();
int x1 = 0, x2 = 0;
if (Math.abs(n1-n2)==1)
{
if (n1 > n2)
{
x1 = n1;
x2 = n2;
}
if(n1 < n2)
{
x1 = n2;
x2 = n1;
String temp = str1;
str1 = str2;
str2 = str1;
}
}
else
{
System.out.print("Invalid input.");
}
for (int i=0; i < x1; i++)
{
for (int j = 0; j < x2; j++)
{
if(str1[i]==str2[j])
{
System.out.println("Extra letter is: " + str1[i]);
break;
}
}
}
}
}

if(str1[i]==str2[j])
{
System.out.println("Extra letter is: " + str1[i]);
break;
}
You're checking if the character matches, and then printing if it does, when your stated intention is the opposite: to check if they differ, and then print if that is the case. Change your == to != and you should get the desired result.
For the sake of clarity, == is the equal-to operator, and != is the not-equal operator.

For you program to work your first string minus second string must be equal to 1:
Math.abs(n1-n2)==1
Fix this piece of code, Hint: is it needed ?

#jjuutz Use below method to get the difference between two strings.
public static String difference(String str1, String str2) {
if (str1 == null) {
return str2;
}
if (str2 == null) {
return str1;
}
int at = indexOfDifference(str1, str2);
if (at == -1) {
return EMPTY;
}
return str2.substring(at);
}
public static int indexOfDifference(String str1, String str2) {
if (str1 == str2) {
return -1;
}
if (str1 == null || str2 == null) {
return 0;
}
int i;
for (i = 0; i < str1.length() && i < str2.length(); ++i) {
if (str1.charAt(i) != str2.charAt(i)) {
break;
}
}
if (i < str2.length() || i < str1.length()) {
return i;
}
return -1;
}

Related

Spaces between elements in RPN expression java

I have a method getRPNString(), which returns Reverse Polish Notation string. I want to split this string by spacebars to calculate it. Now I can't understand how to add spacebars in my RNP string right, because it's not working with two digits numbers.
public class Calc1 {
public static void main(String[] args) {
String in = "((5+3*(4+2)*12)+3)/(1+3)+5";
String out = getRPNString(in);
System.out.println(out);
}
private static String getRPNString(String in) {
LinkedList<Character> oplist = new LinkedList<>();
StringBuilder out = new StringBuilder();
for (int i = 0; i < in.length(); i++) {
char op = in.charAt(i);
if (op == ')') {
while (oplist.getLast() != '(') {
out.append(oplist.removeLast());
}
oplist.removeLast();
}
if (Character.isDigit(op)) {
out.append(op);
/*int j = i + 1;
for (; j < in.length(); j++) {
if (!Character.isDigit(j)) {
break;
}
i++;
}
out.append(in.substring(i, j));*/
}
if (op == '(') {
oplist.add(op);
}
if (isOperator(op)) {
if (oplist.isEmpty()) {
oplist.add(op);
} else {
int priority = getPriority(op);
if (priority > getPriority(oplist.getLast())) {
oplist.add(op);
} else {
while (!oplist.isEmpty()
&& priority <= getPriority(oplist.getLast())) {
out.append(oplist.removeLast());
}
oplist.add(op);
}
}
}
}
while (!oplist.isEmpty()) {
out.append(oplist.removeLast());
}
return out.toString();
}
private static boolean isOperator(char c) {
return c == '+' || c == '-' || c == '*' || c == '/' || c == '%';
}
private static int getPriority(char op) {
switch (op) {
case '*':
case '/':
return 3;
case '+':
case '-':
return 2;
case '(':
return 1;
default:
return -1;
}
}
}
I tried to add spacebars by append(' ') in my StringBuilder variable out. But it' s not right with two digits. I think I totally do not understand how to make it.
For example if input is String in = "((5+3*(4+2)*12)+3)/(1+3)+5"; the out will be 5342+12+3+13+/5+, when I add spacebars to all calls out.append(' ')**out is **5 3 4 2 + * 1 2 * + 3 + 1 3 + / 5 +, so numbers like "12" became "1 2".
Can you help?
Just change the code that you have commented out, right after Character.isDigit(op) to:
int j = i + 1;
int oldI = i;//this is so you save the old value
for (; j < in.length(); j++) {
if (!Character.isDigit(in.charAt(j))) {
break;
}
i++;
}
out.append(in.substring(oldI, j));
out.append(' ');
I changed my method, now it works fine. I fonded my mistake when I wroted
!Character.isDigit(j) but need !Character.isDigit(in.charAt(j)).
private static String getRPNString(String in) {
LinkedList<Character> oplist = new LinkedList<>();
StringBuilder out = new StringBuilder();
for (int i = 0; i < in.length(); i++) {
char op = in.charAt(i);
if (op == ')') {
while (oplist.getLast() != '(') {
out.append(oplist.removeLast()).append(' ');
}
oplist.removeLast();
}
if (Character.isDigit(op)) {
int j = i + 1;
int oldI = i;//this is so you save the old value
for (; j < in.length(); j++) {
if (!Character.isDigit(in.charAt(j))) {
break;
}
i++;
}
out.append(in.substring(oldI, j));
out.append(' ');
}
if (op == '(') {
oplist.add(op);
}
if (isOperator(op)) {
if (oplist.isEmpty()) {
oplist.add(op);
} else {
int priority = getPriority(op);
if (priority > getPriority(oplist.getLast())) {
oplist.add(op);
} else {
while (!oplist.isEmpty()
&& priority <= getPriority(oplist.getLast())) {
out.append(oplist.removeLast()).append(' ');
}
oplist.add(op);
}
}
}
}
while (!oplist.isEmpty()) {
out.append(oplist.removeLast()).append(' ');
}
return out.toString();
}
Now it produce right expression.
Test: input: ((5+3*(4+2)*12)+3)/(1+3)+5
output : 5 3 4 2 + * 12 * + 3 + 1 3 + / 5 +

Why subsequence(a,b).toString() is faster than substring(a,b)?

Why subsequence(a,b).toString() is faster than substring(a,b)?
when i convert my all subsequences to substring it slows up to %7 all the time. why does it happen?
Below is my code;
private static String filterStr(String s)
{
for(int a = 0; a < s.length(); a++)
{
int c = s.charAt(a);
if(((c < 65) || ((c >90) &&(c < 97)) || (c > 122)))
{
if(c!=34 && c!=96 && c!=39)// tırnak değillerse
{
String temp = s.substring(0,a);
temp+= s.subSequence(a+1,s.length());
s = temp;
a--;
}
else
{
if(a !=0) // if not at the beginning
{
if(a == s.length()-1)
s = s.subSequence(0,s.length()-1).toString();
else
s = s.subSequence(0,s.length()-2).toString();
}
else
s = s.subSequence(1,s.length()).toString();
}
}
if(c >= 65 && c <= 90) // convert to lower case first character.
{
String temp = s.substring(1,s.length());
c+=32;
s = (char)c + temp;
}
}
return s;
}
CharSequence subSequence(int beginIndex, int endIndex) {
return this.substring(beginIndex, endIndex);
}
this is the implementation of subSequence method, It can not be faster/slower.

Compares two strings lexicographically using charAt() and without using compareTo() method

if the first string is lexicographically greater than the second string it should return 1,if equal return 0,else -1.It is return 1,-1,0 correctly for some cases,but for this str1 and str2 the return is coming out to be the opposite of the desired output.
public class StringCompare {
static String testcase1 = "helloworld";
static String testcase2 = "hellojavaworld";
public static void main(String args[]) {
StringCompare testInstance = new StringCompare();
int result = testInstance.newCompare(testcase1, testcase2);
System.out.println("Result : " + result);
}
// write your code here
public int newCompare(String str1, String str2) {
int l1 = str1.length();
int l2 = str2.length();
int max = 0;
if (l1 <= l2) {
max = l1;
}
else
max = l2;
int count = 0;
for (int i = 0; i < max; i++) {
char ch1 = str1.charAt(i);
char ch2 = str2.charAt(i);
if (str2.charAt(i) > str1.charAt(i)) {
return - 1;
}
if (str1.charAt(i) > str2.charAt(i)) {
return 1;
}
if (l1 == l2) {
if (ch1 == ch2) {
count++;
}
if (count == max) {
return 0;
}
}
}
if (l1 == l2) return 0;
if (l1 > l2)
return 1;
else
return - 1;
}
}
Here's a simplified answer
public class TestStrings {
public static void main(String[] args) {
System.out.println(compare("Mike", "Mike")); // returns 0
System.out.println(compare("Mikee", "Mike")); // returns 1
System.out.println(compare("Mike", "Mikee")); // returns -1
}
public static int compare(String s1, String s2) {
for (int i = 0; i < Math.min(s1.length(), s2.length()); i++) {
char c1 = s1.charAt(i);
char c2 = s2.charAt(i);
if (c1 > c2) {
return 1;
} else if (c2 > c1) {
return -1;
}
}
if (s2.length() > s1.length()) {
return -1;
} else if (s1.length() > s2.length()){
return 1;
} else {
return 0;
}
}
}
I used a loop, with the stopping condition as the length of the shortest word. If the words are equal after the length of the shortest word, then the longer word is automatically larger. That's what the if statement at the bottom is for.
you can try:
public class StringCompare {
static String testcase1 = "helloworld";
static String testcase2 = "hellojavaworld";
public static void main(String args[]){
StringCompare testInstance = new StringCompare();
int result = testInstance.newCompare(testcase1,testcase2);
System.out.println("Result : "+result);
}
//write your code here
public int newCompare(String str1, String str2){
int l1=str1.length();
int l2=str2.length();
int max=0;
if(l1<=l2)
{
max =l1;
}
else
max=l2;
int count=0;
for (int i =0;i<max;i++) {
char ch1=str1.charAt(i);
char ch2=str2.charAt(i);
if(str2.charAt(i)>str1.charAt(i))
{
return -1;
}
if(str1.charAt(i)>str2.charAt(i))
{
return 1;
}
}
if(l1==l2)
{
return 0;
}else if (l1 < l2){
return -1;
}else{
return 1;
}
}
In this case where String testcase1 = "helloworld" and String testcase2= "hellojavaworld"
your for loop will run from char 'h' to char 'o'(i=0 to i=4) and none of the if conditions inside your for loop will be satisfied and as soon as i gets incremented to 5
//str1.charAt(i)='w' and str2.charAt(i)=j
if(str1.charAt(i)>str2.charAt(i)) //w(ASCII=119) > j(ASCII=106)
{
return 1; //return 1 and control return to the calling function
}
So result=1. Or in short your code is working properly.
You can specify what you want the output to be.

How to know if a given string is substring from another string in Java

Hi
I have to compute if a given string is substring of a bigger string.
For example
String str = "Hallo my world";
String substr = "my"
The method "contains" should return true because str contains substr (false otherwise).
I was looking for something like "contains" at the String class
but I didn't find it. I suppose that the only solution is to use
pattern matching. If this is the case which would be the better (cheapest) way
to do this?
Thanks!
There is a contains() method! It was introduced in Java 1.5. If you are using an earlier version, then it's easy to replace it with this:
str.indexOf(substr) != -1
String str="hello world";
System.out.println(str.contains("world"));//true
System.out.println(str.contains("world1"));//false
Javadoc
String s = "AJAYkumarReddy";
String sub = "kumar";
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == sub.charAt(count)) {
count++;
} else {
count = 0;
}
if (count == sub.length()) {
System.out.println("Sub String");
return;
}
}
use indexOf it will return -1 if no match (contains was added in 1.5, maybe you are using older jdk?) see "contains(CharSequence s)" method in String class in JDK 1.4.2 for details
if (str.indexOf(substr) >= 0) {
// do something
}
I think there is a String function that does just what you are asking: String.indexOf(String).
See this link: http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#indexOf(java.lang.String)
So, then you could write this function:
public boolean isSubstring(String super, String sub) {
return super.indexOf(sub) >= 0;
}
String.indexOf(substr) complexity is O(n2).. Luixv asked a cheaper solution.. But as far as , I know there is no better algorithm than current one.
public boolean isSubString(String smallStr, String largerStr) {
char[] larger = largerStr.toCharArray();
char[] smaller = smallStr.toCharArray();
int i = 0;
for (int j = 0; j < larger.length; j++) {
if(larger[j] == smaller[i]){
if(i == smaller.length -1){
//done we found that this string is substring
return true;
}
i++;
continue;
}else{
if(i > 0){
//that means we encountered a duplicate character before and if string was substring
// it shouldn't have hit this condition..
if(larger.length - j >= smaller.length){
i = 0;
//reset i here because there are still more characters to check for substring..
}else{
//we don't have enough characters to check for substring.. so done..
return false;
}
}
}
}
return false;
}
here is a general method that you can use
public static boolean isSubstring(String s1, String s2) {
if(s1.length() == s2.length())
return s1.equals(s2);
else if(s1.length() > s2.length())
return s1.contains(s2);
else
return s2.contains(s1);
}
public static boolean isSubstring(String s1, String s2){
if(s1.length()<s2.length()) return false;
if(s1.length()==s2.length()) return s1.equals(s2);
for(int i=0;i<=s1.length()-s2.length();i++){
if(s1.charAt(i)==s2.charAt(0)){
int matchLength=1;
for(int j=1;j<s2.length();j++){
if(s1.charAt(i+j)!=s2.charAt(j)){
break;
}
matchLength++;
}
if(matchLength==s2.length()) return true;
}
}
return false;
}
This checks if s2 is a substring of s1.
You can use .substring(int beginIndex,int lastIndex) to check this program. Sample code goes as below:-
public class Test {
public static void main(final String[] args) {
System.out.println("Enter the first String");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
try {
String s1 = br.readLine();
System.out.println("Enter the second String");
String s2 = br.readLine();
boolean result = isSubStr(s1, s2);
if (result == true)
System.out.println("The second String is substring of the first String");
else
System.out.println("The second String is not a substring of the first String");
} catch (IOException e) {
System.out.println("Exception Caught: " + e);
}
}
public static boolean isSubStr(String st1, String s2) {
boolean result = false;
String tem_str = "";
int len1 = st1.length();
int i = 0;
int j;
while (i < len1) {
j = i+1;
while (j <=len1) {
tem_str = st1.substring(i, j);
if (tem_str.equalsIgnoreCase(s2)) {
result = true;
break;
}
j++;
}
i++;
}
return result;
}
}
Go through this method.
visit for tricky code
public static boolean isSubString(String s, String sub) {
int count = 0;
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == sub.charAt(count)) {
count++;
} else {
i-=count;
count = 0;
}
if (count == sub.length()) {
return true;
}
}
return false;
}
Consider the following code:
If substring is present then it returns the start index of substring in a given string
Else returns -1
public static int isSubstring(String str, String pattern)
{
int str_length = str.length();
int pattern_length = pattern.length();
for (int i = 0; i <= str_length - pattern_length; i++)
{
int j;
for (j = 0; j < pattern_length; j++)
if (str.charAt(i + j) != pattern.charAt(j))
break;
if (j == pattern_length)
return i;
}
return -1;
}
String str1 = "Java8 makes Java more powerful";
String str2 = "Java";
char c;
char d;
int count=0;
boolean match = true;
for (int i = 0; i < str1.length(); i++) {
c = str1.charAt(i);
for (int j = 0; j < str2.length(); j++) {
d = str2.charAt(j);
if (c == d) {
match = true;
count++;
if(count== str2.length()){
i = str1.length();
break;
}
i++;
c = str1.charAt(i);
} else {
match = false;
}
}
}
if(match == true){
System.out.println("SubString ");
}
public class StringIsSubString {
public static void main(String[] args) {
String s1 = "wel";
String s2 = "12wlecome123";
boolean isSubStr = isSubStr(s1,s2);
System.out.println(isSubStr);
}
private static boolean isSubStr(String s1, String s2) {
String s3 = "";
int j = 0;
if(s1.length() > s2.length()) {
return false;
} else if(s1.equals(s2)){
return true;
} else {
for(int i=0; i<s1.length();i++) {
for(; j<s2.length();j++) {
if(s1.charAt(i) == s2.charAt(j)) {
s3 = s3 + s1.charAt(i);
break;
}
}
}
if(s3.equals(s1)) {
return true;
}
return false;
}
}
}
*In their any sub string will be count by the form of 1th place of string of substring *
int isSubstring(string s1, string s2) {
int M = s1.length();
int N = s2.length();
for (int i = 0; i <= N - M; i++) {
int j;
for (j = 0; j < M; j++)
if (s2[i + j] != s1[j])
break;
if (j == M)
return i;
}
return -1;
}
int main() {
string s1 = "kumar";
string s2 = "abhimanyukumarroy";
int res = isSubstring(s1, s2);
if (res == -1)
cout << "Not present";
else
cout << "Present at index " << res;
return 0;
}

sorting collections with string elements in java

I have a collections...i wrote code to sort values using my own comparator
my comparator code is
private static class MatchComparator implements Comparator<xmlparse> {
#Override
public int compare(xmlparse object1, xmlparse object2) {
String match1 = object1.getMatchId();
String match2 = object2.getMatchId();
return match1.compareTo(match2);
}
}
I will call Collections.sort(list,new MatchComparator());
Everything is fine but my problem is the sorted list is wrong when i print it...
Input for list
Match19
Match7
Match12
Match46
Match32
output from the sorted list
Match12
Match19
Match32
Match46
Match7
my expected output is
Match7
Match12
Match19
Match32
Match46
to get the order you need, you could either prefix the 1 digit numbers with zero ( eg Match07 ) or you have to split the string in a prefix and a numeric part, and implement the sorting as numeric comparison
The problem is that String.compareTo(..) compares the words char by char.
If all string start with Match, then you can easily fix this with:
public int compare(xmlparse object1, xmlparse object2) {
String match1 = object1.getMatchId();
String match2 = object2.getMatchId();
return Integer.parseInt(match1.replace("Match"))
- Integer.parseInt(match2.replace("Match"));
}
In case they don't start all with Match, then you can use regex:
Integer.parseInt(object1.replaceAll("[a-zA-Z]+", ""));
Or
Integer.parseInt(object1.replaceAll("[\p{Alpha}\p{Punch}]+", ""));
And a final note - name your classes with uppercase, camelCase - i.e. XmlParse instead of xmlparse - that's what the convention dictates.
Implement a function and use it for comparison:
instead of
return match1.compareTo(match2);
use
return compareNatural(match1,match2);
Here is a function which does a natural comparison on strings:
private static int compareNatural(String s, String t, boolean caseSensitive) {
int sIndex = 0;
int tIndex = 0;
int sLength = s.length();
int tLength = t.length();
while (true) {
// both character indices are after a subword (or at zero)
// Check if one string is at end
if (sIndex == sLength && tIndex == tLength) {
return 0;
}
if (sIndex == sLength) {
return -1;
}
if (tIndex == tLength) {
return 1;
}
// Compare sub word
char sChar = s.charAt(sIndex);
char tChar = t.charAt(tIndex);
boolean sCharIsDigit = Character.isDigit(sChar);
boolean tCharIsDigit = Character.isDigit(tChar);
if (sCharIsDigit && tCharIsDigit) {
// Compare numbers
// skip leading 0s
int sLeadingZeroCount = 0;
while (sChar == '0') {
++sLeadingZeroCount;
++sIndex;
if (sIndex == sLength) {
break;
}
sChar = s.charAt(sIndex);
}
int tLeadingZeroCount = 0;
while (tChar == '0') {
++tLeadingZeroCount;
++tIndex;
if (tIndex == tLength) {
break;
}
tChar = t.charAt(tIndex);
}
boolean sAllZero = sIndex == sLength || !Character.isDigit(sChar);
boolean tAllZero = tIndex == tLength || !Character.isDigit(tChar);
if (sAllZero && tAllZero) {
continue;
}
if (sAllZero && !tAllZero) {
return -1;
}
if (tAllZero) {
return 1;
}
int diff = 0;
do {
if (diff == 0) {
diff = sChar - tChar;
}
++sIndex;
++tIndex;
if (sIndex == sLength && tIndex == tLength) {
return diff != 0 ? diff : sLeadingZeroCount - tLeadingZeroCount;
}
if (sIndex == sLength) {
if (diff == 0) {
return -1;
}
return Character.isDigit(t.charAt(tIndex)) ? -1 : diff;
}
if (tIndex == tLength) {
if (diff == 0) {
return 1;
}
return Character.isDigit(s.charAt(sIndex)) ? 1 : diff;
}
sChar = s.charAt(sIndex);
tChar = t.charAt(tIndex);
sCharIsDigit = Character.isDigit(sChar);
tCharIsDigit = Character.isDigit(tChar);
if (!sCharIsDigit && !tCharIsDigit) {
// both number sub words have the same length
if (diff != 0) {
return diff;
}
break;
}
if (!sCharIsDigit) {
return -1;
}
if (!tCharIsDigit) {
return 1;
}
} while (true);
} else {
// Compare words
// No collator specified. All characters should be ascii only. Compare character-by-character.
do {
if (sChar != tChar) {
if (caseSensitive) {
return sChar - tChar;
}
sChar = Character.toUpperCase(sChar);
tChar = Character.toUpperCase(tChar);
if (sChar != tChar) {
sChar = Character.toLowerCase(sChar);
tChar = Character.toLowerCase(tChar);
if (sChar != tChar) {
return sChar - tChar;
}
}
}
++sIndex;
++tIndex;
if (sIndex == sLength && tIndex == tLength) {
return 0;
}
if (sIndex == sLength) {
return -1;
}
if (tIndex == tLength) {
return 1;
}
sChar = s.charAt(sIndex);
tChar = t.charAt(tIndex);
sCharIsDigit = Character.isDigit(sChar);
tCharIsDigit = Character.isDigit(tChar);
} while (!sCharIsDigit && !tCharIsDigit);
}
}
}
a better one is here
The comparison is lexicographic and not numerical, that's your problem. In lexicoraphic ordering, 10 comes before 9.
See this question for open source implementation solutions. You can also implement your own string comparison, which shouldn't be that hard.
It seems that you expect not what the String.compareTo() really is. It performs so called lexicographical comarsion, but you try to compare it by number. You need to modify the code of your comparator.
#Override
public int compare(xmlparse object1, xmlparse object2) {
String match1 = object1.getMatchId();
String match2 = object2.getMatchId();
Long n1 = getNumber(match1);
Long n2 = getNumber(match2);
return n1.compareTo(n2);
}
where getNumber() extracts the last nuber from string "matchXX"

Categories