How to compare two strings, of different length to find identical substring - java

The problem is:
Client accounts are filed under a classification system using codes eg MA400. I need a method that will reset the original MA400 to an updated code such as MA400.4. If the new code has 5 characters to which the original is reset then the method returns true. Not the best wording but that is all I have right now.
It hasn't been specified if the characters need to be in the same order, eg.
String str = "abc123";
String newStr = "xyz123abc";
I am assuming they need to be in the same order. So the above strings would only have 3 like characters.
char[]array = str.toCharArray();
char[]array2 = newStr.toCharArray();
I am thinking now to use a compareTo method on the two arrays, but I am not sure how this would work exactly. Perhaps I could use a for loop to stop comparing after the final element in the shortest string but not entirely sure if I can do much with that.
I feel like I am going about this in the wrong way and there is a less complicated way to check for like characters in a string?

From what I understand something like this will work. Remember this will only count unique characters. Order does not matter
public static boolean matchingChar(final String st1, final String st2) {
if(st1 == null || st2 == null || st1.length() < 5 || st2.length() < 5) {
return false;
}
//This is if you wish unique characters to be counted only
//Otherwise you can use simple int count = 0
HashSet<Character> found = new HashSet<Character>();
//found.size() < 5 so the loop break as soon as the condition is met
for(int i = 0; i < st1.length() && found.size() < 5; i++) {
if(st2.indexOf(st1.charAt(i)) != -1) {
found.add(st1.charAt(i));
}
}
return found.size() >= 5;
}

Related

Why is this code not executing properly? Longest substring problem

So I'm trying to solve the Longest Substring Without Repeating Character problem in a webpage and when I'm trying to upload it it will show me this bug:
class Solution {
public int lengthOfLongestSubstring(String s) {
HashSet<Character> hash = new HashSet<>();
int count = 0, finalCount = 1;
char prevChar = s.charAt(0);
hash.add(prevChar);
for (int i = 1; i < s.length(); i++)
{
char character = s.charAt(i);
if (!hash.contains(character)){
hash.add(character);
count++;
if (count > finalCount) finalCount = count;
}
else{
hash.clear();
hash.add(character);
count = 1;
}
prevChar = character;
}
return finalCount;
} }
Is there anything wrong with it?
If not, do you think my algorithm was efficient? I can't compare its performance since the webpage won't let me upload it.
You call s.charAt(0) in line 5. I imagine they pass in the empty string as a test case and you are getting an out of bounds exception. Prior to line 5 add a check to see if the string length is 0 and if it is return 0.
According to the error description it's doing a dummy-spit at line 5 of the Solution class.
Based on the picture that's:
char prevChar = s.charAt(0);
The error is ArrayIndexOutOfBounds which generally indicates you tried to get more out of something than was actually there (e.g. running over the end of an array).
Here I'd suggest maybe putting in some System.out.println lines at line 3 to sanity check the method parameter, e.g.:
(a) if the input String s is null
or
(b) if the input String s is empty (e.g. "")
charAt(0) will get the first character, but if there are zero characters then trying to get the 1th character is an error, no?
NB: something like this:
System.out.println("Input was :" + s + ":");
Will show both of those conditions, as either:
Input was ::
for an empty String
Input was :null:
for a null String

How to create a loop for

I need to create a loop that adds "o" after each consonant
I am going to walk you through what I corrected and changed in your code to make it work in order to make it quick and easy for you to comprehend why your code doesn't work and why my answer fixes it.
The mistakes you made are basic ones and frankly you shouldn't have to much of a hard time correcting them yourself if you would use a debugger that walks you step by step in how your code works. You should look on how to use a debugger (for example the debugger used in Eclipse, hopefully you are using an IDE to make your life easier).
Firstly, when you are looking for a consonant in your code, you are only walking through the half of it because of your condition for(int x = 0; x<20; x++) since your string holding the consonants if of a length of 40 characters. This means you are missing consonants like the letter s.
Then you are correctly the consonants you find according to your Swedish language game. But you are never handling characters that are not of these found consonants. You should make a case where you handle these "non consonant" letters, may they be vowels or any kind of character (like punctuation marks and so on). I am fixing this with the use of a simple boolean here.
Keep in mind that my goal here is to change your code as little as I can, thus I went for adding a boolean to handle your cases (checking the presence of a consonant). There are, obviously, many other ways to implement what you are trying to do.
Here come the changes you should add to your code:
/*This comes after your print "På rövarspråk:"*/
boolean isConsonant = false; //Boolean to check wether there is a consonant or not
for(int i = 0; i<length; i++) {
//You didn't go through the whole consonants list you made with your prevision condition
for(int x = 0; x<consonants.length; x++){
if(array[i] == consonants[x])
{
isConsonant = true; //Set the boolean accordingly
String add = array[i]+"o"+array[i];
slang = slang + add;
break;
}
}
if(!isConsonant){ //If we don't have a consonant, add the char to the result string
slang += array[i];
}
isConsonant = false; //Reset the boolean for the next character
}
/*Here you can print the result (slang) if you want, as you did*/
so the idea is to dublicate consonants and put "o" between them, like t becomes tot, s becomes sos. Vocals are just copied. So you need a method that tells you if a given character is a vocal or consonant to base your decision on that.
public static boolean isConsonant(char inputChar){
final String consonantsx = "bBcCdDfFgGhHjJkKlLmMnNpPqQrRsStTvVwWxXzZ";
char consonants[] = consonantsx.toCharArray(); // String to charr
for(int i=0; i < consonants.length;i++){
if(inputChar == consonants[i]){ //note that in Strings u use the equals method instead of "=="
return true;
}
}
return false;
}
Given this method you can use it in the "translator method".
public String rovarSpraket(String normalString) {
char[] array = normalString.toCharArray(); // Input to a char array
System.out.println("På rövarspråk:");
String slang = "";
for (int i = 0; i < normalString.length(); i++) {
String add = "" + array[i];
if(Goran.isConsonant(array[i])){
add += "o" + array[i];
}
slang += add;
}
return slang;
}
This translates stubborn to sostotubobboborornon like in the wikipedia article https://en.wikipedia.org/wiki/R%C3%B6varspr%C3%A5ket.

Unexpected type error with arrays

I have a lab that I have to do for my computer class and i have an error that I can't seem to figure out. I get the error on the first if statement, if(something.indexOf(x) = "a"). I want to change the other if statements to be of that form.
The error I get is:
unexpected type
required:variable: found; value
Scanner in = new Scanner(System.in);
String[] input = new String[1000];
String[] output = new String[1000];
int x = 0;// All purpose counter
int y = 0;//Second purpose counter
boolean ends = false;
boolean starts = false;
/**
* This method is supposed to take the dna array and create an rna array from it to return
* to the main method wherever this method is called.
*
* #param String[] input The array that contains the dna sequence
* #return String[] output The array that contains the mRNA we just created in this method
*/
public void makeRNA()
{
System.out.println("Enter a simple DNA Sequence, make sure the amount of variables are a multiple of 3.");
String something = in.nextLine();
while(x < 1000)
{
if(something.indexOf(x) = "a")
{
output[x] = "u";
}
else if(input[x] == "c")
{
output[x] = "g";
}
else if(input[x] == "g")
{
output[x] = "c";
}
else if(input[x] == "t")
{
output[x] = "a";
}
x++;
}
for(x = 0 ; x < 1000; x++)
{
System.out.println(output[x]);
}
}
The problem seems to be here: if(something.indexOf(x) = "a")
To get the character at index x you need to use charAt().
Instead of the assignment operator, you need to use == (comparison operator).
Compare it with a char and not a String, because charAt() returns a char. So change "a" to 'a'.
So your statement should finally look like:
if(something.charAt(x) == 'a')
if(something.indexOf(x) = "a") ,= is assignment operator. you need == operator in your if statement unless the assignment results in a boolean.
also, indexOf() returns an int ,so you can't use == with "a", use equals() for string comparison.
java if statement doesn't work like c or c++.
Ramanlfc is correct in saying use == instead of = because just a single equals sign is an assignment operator.
However, I'm not sure your IF statements are doing what you want them to do. The indexOf() method returns an integer and you're trying to compare it to a string, an object, using == (equals). If you want to compare two strings use the .Equals() method. You cannot use == on an object, which is what a string is. However, you can use == on chars because they are primitive types. To specify a char use single quotes not double quotes (double quotes specifies a string which is currently how you have your if statement set up). I'm assuming java will use the hex value of the char to compare it to a number. Once again, I'm not sure what you're trying to achieve, but just some helpful advice!
I'm assuming you want something like the following:
if(stringMsg.charAt(INDEXVALUE) == 'a')
This gets the character at the specified value in the string and checks to see if it is the same (equal to) the char a. Remember characters in a string are number 0 to (length - 1).
The problem is this line of code:
if(something.indexOf(x) = "a") // it should be "==" instead of "="
The correct code is:
if(something.indexOf(x) == "a")
Please note that if(something.indexOf(x) = "a") will always return true in java.

Faster way to split a string in java then add to an ArrayList

For a school project I was asked to write a simple math parser in Java. The program works fine. So fine that I used NetBeans profiler tool to check the performance of the program. For that I made a loop of 1000 calls to the math parser of the following expression: "1-((x+1)+1)*2", where x was replaced by the current loop count. It took 262ms. The thing is, it took 50% of the time in the method splitFormula, which I shall present below:
private static void splitFormula(String formula){
partialFormula=new ArrayList<>();
for(String temp: formula.split("\\+|\\-|\\*|\\/"))
partialFormula.add(temp);
}
, where partialFormula is an ArrayList of Strings. To numerically evaluate an expression I need to call the splitFormula method various times so I really need to clear the contents of the partialFormula ArrayList - first line.
My question is: is there a faster way to split a string then add the partial strings to the an arraylist? Or is there some other method that can be used to split a string then use the substrings?
Regular expressions can slow things down (String#split uses regex). In general, if you want to write easy code, regex is good, but if you want fast code, see if there is another way. Try doing this without regex:
Edit: This should be a better method (keep track of the indices instead of append to a StringBuilder):
private static void splitFormula(String formula){
partialFormula.clear(); // since there is a method for this, why not use it?
int lastIndex = 0;
for (int index = 0; index < formula.length(); index++) {
char c = formula.charAt(index);
if (c == '-' || c == '+' || c == '*' || c == '/') {
partialFormula.add(formula.substring(lastIndex, index));
lastIndex = index + 1; //because if it were index, it would include the operator
}
}
partialFormula.add(formula.substring(lastIndex));
}
StringBuilder approach:
private static void splitFormula(String formula){
partialFormula.clear();
StringBuilder newStr = new StringBuilder();
for (int index = 0; index < formula.length(); index++) {
char c = formula.charAt(index);
if (c == '-' || c == '+' || c == '*' || c == '/') {
partialFormula.add(newStr.toString());
newStr.setLength(0);
} else {
newStr.append(c);
}
}
partialFormula.add(newStr.toString());
}
If we look at the source code for String#split, it becomes apparent why that is slower (from GrepCode):
public String[] split(String regex, int limit) {
return Pattern.compile(regex).split(this, limit);
}
It compiles a regex every time! Thus, we can see that another way of speeding up the code is to compile our regex first, then use the Pattern#split to split:
//In constructor, or as a static variable.
//This regex is a better form of yours.
Pattern operatorPattern = Pattern.compile("[-*+/]");
...
private static void splitFormula(String formula){
partialFormula.clear();
for(String temp: operatorPattern.split(formula)) {
partialFormula.add(temp);
}
}
You don't need a for loop. split returns an array, and you can create an ArrayList out of the array:
partialFormula = new ArrayList<>(Arrays.asList(formula.split("\\+|\\-|\\*|\\/")));
Whether this is significantly faster or not, I don't know.
Try pre-allocating the ArrayList beforehand so we do not have to pay for reallocation when the list grows. The number 20 below is just a placeholder. Pick a number that is a little bigger than the largest expression you expect.
partialFormula=new ArrayList<String>(20);
See this question for a discussion of what this might gain you.
This will create an arrayList of strings.
String a= "1234+af/d53";
char [] blah=a.toCharArray();
ArrayList<String> list=new ArrayList<String>();
for (int i = 0; i < blah.length; i++) {
list.add(Character.toString(blah[i]));
}

Code correction suggestion using Java libraries for strings?

I know there is an easier way of making things work to check whether a string is a palindrome or not, but I wanted to try it using library functions and I came up with the code below.
public boolean isPalindrome1(String input)
{
int length = input.length()/2;
if(input.length()%2!=0)
{
length = length + 1;
}
return(input.substring(0,length).equals(new StringBuilder(input.substring(length, input.length())).reverse().toString()));
}
I'm trying to check whether half the string is equal to the other half's reverse. But it is getting messed up for odd and even lengths. Can someone point corrections in this where it will work for odd, even lengths as well as empty string and string of length = 1.
You're already using reverse(). Why can you not compare the input String with the reverse? Isn't that exactly what you're wanting in the first place? No need to be splitting things in half in a complicated way.
you can:
return new StringBuilder(input).reverse().toString().equals(input);
here you go as you want to know :
public boolean isPalindrome(String input) {
for (int i = 0; i < input.length() / 2; i++) {
if (input.charAt(i) != input.charAt(input.length() - 1 - i)) {
return false;
}
}
return true;
}

Categories

Resources