I am needed find number of mismatching characters between two strings. Currently i m doing it by converting strings into char Arrays and comparing element by element.
Is there any other way to achieve above requirement.
Note: consider string as lower case
Inputs :
input
utput
Output :
2
StringUtils in Apache commons.lang has a method for getting the Levenshtein distance of two strings.
If the two string are of different size the following code you return the total mismatch of alphabets.
You can try this -
String ip1 = "input"; // input1
String ip2 = "utput"; // input2
int count = 0; // difference in string
String ipx2 = ip2;
for (int j = 0; j <= ip2.length(); j++) {
int value = ip1.indexOf(ipx2);
if (value != -1) {
if (("").equals(ipx2)) { // if the second string is blank after continous reducing
count = ip1.length() + ip2.length();
} else {
count = ip1.length() + ip2.length() - 2 * ipx2.length();
}
break;
} else {
count = ip1.length() + ip2.length(); // if there is no match at all
}
ipx2 = ip2.substring(j);
}
System.out.println("" + count);
}
You will have to check whether the inputs have some data or not. I have not done that check.
This is the way you are describing, but it is the simplest way of implementing:
int counter = 0;
for(int i = 0; i < str1.length(); i++) if(str1.charAt(i) != str2.charAt(i)) counter++;
They can be fit on just two lines of code, without explicitly creating a whole new character array.
Related
Trying to search for patterns of letters in a file, the pattern is entered by a user and comes out as a String, so far I've got it to find the first letter by unsure how to make it test to see if the next letter also matches the pattern.
This is the loop I currently have. any help would be appreciated
public void exactSearch(){
if (pattern==null){UI.println("No pattern");return;}
UI.println("===================\nExact searching for "+patternString);
int j = 0 ;
for(int i=0; i<data.size(); i++){
if(patternString.charAt(i) == data.get(i) )
j++;
UI.println( "found at " + j) ;
}
}
You need to iterate over the first string until you find the first character of the other string. From there, you can create an inner loop and iterate on both simultaneously, like you did.
Hint: be sure to look watch for boundaries as the strings might not be of the same size.
You can try this :-
String a1 = "foo-bar-baz-bar-";
String pattern = "bar";
int foundIndex = 0;
while(foundIndex != -1) {
foundIndex = a1.indexOf(pattern,foundIndex);
if(foundIndex != -1)
{
System.out.println(foundIndex);
foundIndex += 1;
}
}
indexOf - first parameter is the pattern string,
second parameter is starting index from where we have to search.
If pattern is found, it will return the starting index from where the pattern matched.
If pattern is not found, indexOf will return -1.
String data = "foo-bar-baz-bar-";
String pattern = "bar";
int foundIndex = data.indexOf(pattern);
while (foundIndex > -1) {
System.out.println("Match found at: " + foundIndex);
foundIndex = data.indexOf(pattern, foundIndex + pattern.length());
}
Based on your request, you can use this algorithm to search for your positions:
1) We check if we reach at the end of the string, to avoid the invalidIndex error, we verify if the remaining substring's size is smaller than the pattern's length.
2) We calculate the substring at each iteration and we verify the string with the pattern.
List<Integer> positionList = new LinkedList<>();
String inputString = "AAACABCCCABC";
String pattern = "ABC";
for (int i = 0 ; i < inputString.length(); i++) {
if (inputString.length() - i < pattern.length()){
break;
}
String currentSubString = inputString.substring(i, i + pattern.length());
if (currentSubString.equals(pattern)){
positionList.add(i);
}
}
for (Integer pos : positionList) {
System.out.println(pos); // Positions : 4 and 9
}
EDIT :
Maybe it can be optimized, not to use a Collection for this simple task, but I used a LinkedList to write a quicker approach.
The code should do the following:
Write a method called compress that takes a string as input, compresses it using RLE, and returns the compressed string. Case matters - uppercase and lowercase characters should be considered distinct. You may assume that there are no digit characters in the input string. There are no other restrictions on the input - it may contain spaces or punctuation. There is no need to treat non-letter characters any differently from letters.If a character does not repeat, it should be left alone.
For example, consider the following string:
qwwwwwwwwweeeeerrtyyyyyqqqqwEErTTT
After applying the RLE algorithm, this string is converted into:
q9w5e2rt5y4qw2Er3T
However, when I upload it the grading system gives a zero and gives me the following hints:
Double check your algorithm for logical errors (2 occurrences)
Double check that you are compressing single characters properly (2 occurrences)
I am not sure where the errors are since all the test cases I used the output was correct.
Here is my compress method:
public static String compress (String original)
{
StringBuilder compressed = new StringBuilder();
char letter = 0;
int count = 1;
for (int i = 0; i < original.length(); i++) {
if (letter == original.charAt(i)) {
count = count + 1;
}
else {
compressed = count !=1 ? compressed.append(count) : compressed;
compressed.append(letter);
letter = original.charAt(i);
count = 1;
}
}
compressed = count !=1 ? compressed.append(count) : compressed;
compressed.append(letter);
return compressed.toString();
}
Base on the definition of RLE https://en.wikipedia.org/wiki/Run-length_encoding
Single character should have also have a count in front of them.
So the result should be
1q9w5e2r1t5y4q1w2E1r3T
Instead of
q9w5e2rt5y4qw2Er3T
Therefore, you need to change
compressed = count !=1 ? compressed.append(count) : compressed;
To just
compressed.append(count);
Below is one way to resolve it, I treat the previousLetter a bit differently from you:
public static String compress(String original) {
if (original.isEmpty()) return "";
StringBuilder compressed = new StringBuilder();
char previousLetter = original.charAt(0); // initialize the previous letter
int count = 1;
// start searching from the second letter
for (int i = 1; i < original.length(); i++) {
if (previousLetter == original.charAt(i)) {
count = count + 1;
} else {
compressed.append(count);
compressed.append(previousLetter);
previousLetter = original.charAt(i);
count = 1;
}
}
compressed.append(count);
compressed.append(previousLetter);
return compressed.toString();
}
I have to create a program that takes a user input (a number) and then the program should have that number and apply a search to the array and output the corresponding title by matching the index and the number the user inputted. However during run time, nothing happens. I have set breakers in my code and noticed a problem with the for loop (search algorithm). Please help me and let me know what is wrong is my search algorithm. What I am trying to do is use the number of that the user inputs to match a index and then output the book title that is stored in the index.
private void btnFindActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
// declares an array
String[] listOfBooks = new String [101];
// assigns index in array to book title
listOfBooks[1] = "The Adventures of Tom Sawyer";
listOfBooks[2] = "Huckleberry Finn";
listOfBooks[4] = "The Sword in the Stone";
listOfBooks[6] = "Stuart Little";
listOfBooks[10] = "Treasure Island";
listOfBooks[12] = "Test";
listOfBooks[14] = "Alice's Adventures in Wonderland";
listOfBooks[20] = "Twenty Thousand Leagues Under the Sea";
listOfBooks[24] = "Peter Pan";
listOfBooks[26] = "Charlotte's Web";
listOfBooks[31] = "A Little Princess";
listOfBooks[32] = "Little Women";
listOfBooks[33] = "Black Beauty";
listOfBooks[35] = "The Merry Adventures of Robin Hood";
listOfBooks[40] = "Robinson Crusoe";
listOfBooks[46] = "Anne of Green Gables";
listOfBooks[50] = "Little House in the Big Woods";
listOfBooks[52] = "Swiss Family Robinson";
listOfBooks[54] = "The Lion, the Witch and the Wardrobe";
listOfBooks[54] = "Heidi";
listOfBooks[66] = "A Winkle in Time";
listOfBooks[100] = "Mary Poppins";
// gets user input
String numberInput = txtNumberInput.getText();
int number = Integer.parseInt(numberInput);
// Linear search to match index number and user input number
for(int i = 0; i < listOfBooks.length - 1; i++) {
if (listOfBooks.get(i) == number) {
txtLinearOutput.setText(listOfBooks[i]);
break;
}
}
*There is a problem with the listOfBooks.get in the if statement. Also I need to apply a binary search that would search the same array just using the binary method. Need help to apply this type of binary search.
How could I make a statement that checks if the int number is equal to an index?
Note that the following code is just an example of what I have to apply. Variables are all for example purposes:
public static Boolean binarySearch(String [ ] A, int left, int right, String V){
int middle;
if (left > right) {
return false;
}
middle = (left + right)/2;
int compare = V.compareTo(A[middle]);
if (compare == 0) {
return true;
}
if (compare < 0) {
return binarySearch(A, left, middle-1, V);
} else {
return binarySearch(A, middle + 1, right, V);
}
}
you can avoid for loop and check condition by just giving number like this: txtLinearOutput.setText(listOfBooks[number-1]);
remove your code
// Linear search to match index number and user input number
for(int i = 0; i < listOfBooks.length - 1; i++) {
if (listOfBooks.get(i) == number) {
txtLinearOutput.setText(listOfBooks[i]);
break;
}
with
try{
int number = Integer.parseInt(numberInput);
if(number>0 && number<101){
txtLinearOutput.setText(listOfBooks[number-1]);
}else{
// out of range
}
}catch(Exception e){
// handle exception here
}
You are comparing if (listOfBooks.get(i) == number) it is wrong, you should compare: if (i == number), becouse you need compare element position.
This isn't a binary search answer. Just an implementation of HashMap. Have a look at it.
HashMap<String, Integer> books = new HashMap();
books.put("abc", 1);
books.put("xyz", 2);
books.put("pqr", 3);
books.put("lmo", 4);
System.out.println(books.getValue("abc");
Using the inbuilt BinarySearch.
String []arr = new String[15];
arr[0] = "abc";
arr[5] = "prq";
arr[7] = "lmo";
arr[10] = "xyz";
System.out.println(Arrays.binarySearch(arr, "lmo"));
How to compare Strings using binary search.
String[] array = new String[4];
array[0] = "abc";
array[1] = "lmo";
array[2] = "pqr";
array[3] = "xyz";
int first, last, middle;
first = 0;
last = array.length - 1;
middle = (first + last) / 2;
String key = "abc";
while (first <= last) {
if (compare(array[middle], key))
first = middle + 1;
else if (array[middle].equals(key)) {
System.out.println(key + " found at location " + (middle) + ".");
break;
} else {
last = middle - 1;
}
middle = (first + last) / 2;
}
if (first > last)
System.out.println(key + " is not found.\n");
}
private static boolean compare(String string, String key) {
// TODO Auto-generated method stub
for (int i = 0; i < Math.min(string.length(), key.length()); ++i)
if (string.charAt(i) < key.charAt(i))
return true;
return false;
}
Your linear search code looks something like this
try{
txtLinearOutput.setText(listOfBooks[yourNumber]);
}
catch(IndexOutOfBoundsException ie){
// prompt that number is not an index
}
catch(Exception e){
// if any other exception is caught
}
What you are doing here:
if (listOfBooks.get(i) == number) {
is that you are matching the content of the array with the input number, which is irrelevant.
You can directly use the input number to fetch the value stored at the index.
For example:
txtLinearOutput.setText(listOfBooks[number-1]);
Additionally, int number = Integer.parseInt(numberInput); should be placed within try-catch block to validate input number parsing. And you can check if the input number is within the range of the array to avoid exceptions like:
try{
int number = Integer.parseInt(numberInput);
// Linear search to match index number and user input number
if (number > 0 && number <=100) {
txtLinearOutput.setText(listOfBooks[number-1]);
} else {
// Display error message
}
} catch(Exception e) {
// Handle exception and display error message
}
And for using binary search, the string array need to be sorted. You can use Arrays.sort() method for sorting it.
And regarding using binary search, you can use Java Arrays Binary Search method
I tried to count the occurrence of alphabets in a string, but I substitue them with numbers to make it clearer. Then when I run that code, it doesnt display the results I want.I dont really know why...Please help!! Thank you so much!!
Scanner Scanner1 = new Scanner(System.in);
out.println("Please type in a string below.");
String UserInput = Scanner1.nextLine();
String Index = "12345";
int length = 2;//Modified
int[] count = new int[length];
int length2 = 5; //Modified
int n1 = 0;
int n2 = 0;
out.println(UserInput.charAt(n1));//Modified
out.println(Index.charAt(n2));//Modified
for (int i = 0; i < length; i++) {
if (UserInput.charAt(n1) == Index.charAt(n2)) {
n1++;
count[length - (length - n1)]++;
} else {
n2++;
if(n2==length2)
{
n2 = n2-length2;
}
}
}
A relatively short and neat way to count a specific character in a string is using the return value of the replaceAll method:
public static int countChar(final String str, final char c) {
return str.replaceAll("[^" + c + "]","").length();
}
The pattern [^x] (x can be replaced with any char (or amount of different chars)) will match everything in a given String except x. So [^T] of TEST would replace E and S with the given replacement (which is "" (nothing)) and keeps the Ts. The method would return TT. If you count that length, you'll receive the count of the searched character of the given string.
The example
System.out.println(countChar("TEST", 'T'));
System.out.println(countChar("TEST", 'E'));
System.out.println(countChar("TEST", 'S'));
prints
2
1
1
(keep in mind that is method is case sensitive)
use collections like Hashmap. Here Character stores every unique character encountered and Integer stores the count of every character whenever it is encountered.
I wrote a method that loops through a string and adds '/n' to create a line length that was given in the parameters. That description is not the best but it's hard to describe so look at the code below. Thanks in advance!
My Code:
public static String lineLength(String str, int length){
int totalLength = 0; //total length of the document
int lengthConst = 0; //constant value of the length for the loop
int nLength = 0; // length of \n = 2 characters
String work1, work2; //Strings to work with in the loop. Used as string buffers in substrings
if(str != null){
totalLength = str.length();
lengthConst = length;
}
if(length < 1){
throw new NullPointerException("Length must be >= 1");
}
/*
Main Loop: check again if length is not zero, check if totalLength is not zero,
check if pseudoCursor is not zero, check if length is less than or equal to totalLength
*/
while((length != 0) && (totalLength != 0) && (lengthConst != 0) && (length <= totalLength)){
work1 = str.substring(0, length); //store string of beginning to line length
work2 = str.substring(length + nLength, str.length()); //store string from length to end
work1 = work1.concat("\n"); //add new line
str = work1.concat(work2); //add work1 and work2 and store in str
nLength += 1; //nLength increases by 2 because we are going to add another \n
length += length;
}
return str;
}
When provided with the string "Daniel" and the new line length of 2 this is the run when printed to the console:
run:
Da
n
el
BUILD SUCCESSFUL (total time: 4 seconds)
I'd recommend using a for loop. I think it would be easier than what you are currently doing. Generally for loops go as such:
for(START POSITION, CONTROL, ITERATION PATTERN){
CODE
}
I'd read more about for loops here:
http://www.tutorialspoint.com/java/java_loop_control.htm
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
The String object has a method .length() which will be used for the control of the loop. You want to iterate by 2 (because that's how you're separating it the words). You also want to start at 1 (usually the starting position is 0 but in this case we want 1):
String word = "Daniel";//starting word
String outputWord = "";//make it empty quotes so you can concatenate to it.
//if the size of word is less than 2, then print so
//else do the code below
for(int i = 1; i < word.length(); i = i+2){
outputWord = outputWord + word.get(i-1) + word.get(i) + "\n";
}
//check if the length was of word was odd. if so, then add the last character to outputWord
System.out.println(outputWord);
NOTE: This will only working assuming your word variable is at least 2 in size. I'll leave that error handling up to you to write. You'll also want to handle in odd length cases as well.
Here's a much simplified version
public static String lineLength(String str, int length) {
StringBuilder sb = new StringBuilder();
while(true) {
if(str.length() <= length) {
sb.append(str);
break;
}
sb.append(str.substring(0, length));
sb.append("\n");
str = str.substring(length);
}
return sb.toString();
}
You still need to understand what was wrong with your solution so that you learn from it and can apply that knowledge to the code you write in the future. Step through both this and your original code in a debugger and observe carefully what is happening.