Right now, I have a method that is supposed to use binary search to find if a prefix is in a list.
For example, user enters "ca" and if dictionary contains "cat", then the method should return true.
This is my method and along it is a helper method. The problem I have right now is that when I call the recursive method and the prefix is greater than the words in the dictionary, I will get an index out of bounds error because of the substring() method.
I'm using this method in conjunction with a recursive function in order to find all permutations of a string. (The generateWords() method).
How can I modify this function in order to check whether a prefix is in a list of words given that the list of words have words of varying lengths?
public boolean findPrefix(String Prefix){
return findBinaryPrefix(listOfWords, Prefix,0, listOfWords.size()-1, 0);
}
/**
* Helper function for findPrefix.
* #param list arraylist
* #param prefix prefix you want to find
* #param low lowest index
* #param high highest index of the array.
* #return returns true if prefix is in the dictionary, else false.
*/
private boolean findBinaryPrefix(ArrayList<String> list, String prefix, int low, int high, int prefixLength){
int charCounter = prefixLength;
if(low>high){
return false;
}
int mid = (low+high)/2;
if(list.get(mid).substring(0, charCounter).equals(prefix.substring(0, charCounter))){
//If the word is equal, then that's the base case.
return true;
}
else if (list.get(mid).substring(0, charCounter).compareTo(prefix.substring(0, charCounter)) < 0){
return findBinaryPrefix(list, prefix, mid+1, high, charCounter);
}
else
return findBinaryPrefix(list, prefix, low, mid-1, charCounter);
}
private ArrayList<String> generateWords(Dictionary dict,String prefix, String seq){
if(seq.length() == 0){
if(dict.findWord(prefix)){
permList.add(prefix);
}
}
else{
for(int i = 0;i<seq.length(); i++){
if(!dict.findPrefix(prefix)){break;}
//if prefix is not even in dictionary, don't bother generating.
//generate permutations when the character is in a different position with each iteration of the loop.
generateWords(dict, prefix + seq.charAt(i) ,seq.substring(0,i) + seq.substring(i+1, seq.length()));
}
}
return permList;
}
add
if(list.get(mid).length() < charCounter) {
//do something
}
Related
I've written a recursive program in java that takes an array of characters and with two methods, one switching places of the two leftmost tiles and the other moving the rightmost tile to the left of the leftmost tile. It then returns the order of moves which makes the array in alphabetical order with the smallest number of moves. It seems to be working but I'm also supposed to set a max depth (15), and what I wonder is what do I return when it has reached max depth? It seems to be working right now, but I'm not sure it's correct.
This is part of the code:
public static String Sorter(char[] letters){
int nrOfMoves = 0;
return Sorter(letters,nrOfMoves);
}
private static String Sorter(char[] letters, int nrOfMoves){
if(sorted(letters)) return "";
if(nrOfMoves >= 15) return "" ; //??
switchLeft(letters);
String moveb = "b" + Sorter(letters,nrOfMoves+1);
switchLeft(letters);
rightToLeft(letters);
String moves = "s" + Sorter(letters,nrOfMoves+1);
leftToRight(letters);
if(moves.length()<moveb.length()) return moves;
return moveb;
}
The example seems fine. Personally, I would make use of nrOfMoves++ instead of nrOfMoves+1
and I would have it count down (number of moves left instead of number of moves performed). This makes sure that your Sorter method does not need to know at what depth it needs to stop. It just gets a limit of how many more recursions it can perform
public static String Sorter(char[] letters){
int nrOfMoves = 15;
return Sorter(letters,nrOfMoves);
}
private static String Sorter(char[] letters, int nrOfMoves){
if(sorted(letters) || nrOfMoves <= 0){
return "";
}
switchLeft(letters);
String moveb = "b" + Sorter(letters,nrOfMoves--);
switchLeft(letters);
rightToLeft(letters);
String moves = "s" + Sorter(letters,nrOfMoves--);
leftToRight(letters);
if(moves.length()<moveb.length()) return moves;
return moveb;
}
I'm currently trying to use a function that compares the left and right side character to return a true or false Boolean value as to whether the string entered by the user is a palindrome or not, but I get a vague error statement to do with line 44. Not sure how to proceed. I am a beginner-level Java programmer who is open-minded and willing to learn, so don't roast me to hard haha.
import java.util.Scanner;
/**
*
* #author owner
*/
public class Q2_RecursivePalidrome {
public static void main(String[] args) {
int leftSideCharacter = 0;
int rightSideCharacter = 0;
Scanner scan = new Scanner (System.in);
System.out.println("Enter word to check whether palidrome: ");
String userInput = scan.next();
char[] checkPalidrome = userInput.toCharArray(); // creates an array of characters
System.out.println(isPalidrome(checkPalidrome, leftSideCharacter, rightSideCharacter));
}
public static boolean isPalidrome(char[] checkPalidrome, int leftSideCharacter, int rightSideCharacter) {
leftSideCharacter = 0;
rightSideCharacter = checkPalidrome.length - 1; // java arrays start at 0, not 1.
if (rightSideCharacter > leftSideCharacter) { // check both ends of string character by character
// to be palidrome, both sides of string should be same
//
if (checkPalidrome[leftSideCharacter] == checkPalidrome[rightSideCharacter]) {
return (isPalidrome(checkPalidrome, leftSideCharacter + 1, rightSideCharacter - 1));
}
else {
return false;
}
}
return true;
}
}
There are a couple main issues here, but you have the right idea:
Your recursive function uses left and right indices to determine which characters to compare in the test string. However, these two pointers are immediately set to the left and right ends of the string when the function is called, so they never recursively move towards the middle. Since the base case where the indices are equal is unreachable, the stack overflows. Remember, these calls are identical all the way down the stack, but with different parameters, so one-time "set up" tasks like setting initial indices should be moved outside of the recursive function.
Your initial pointer indices are 0, 0. This is an inaccurate "set up" call to the recursive function--it should be 0, string.length - 1.
Here is code that fixes these problems and cleans up comments and variable names:
import java.util.*;
public class Q2_RecursivePalidrome {
public static void main(String[] args) {
String test = "racecar";
System.out.println(isPalidrome(test.toCharArray(), 0, test.length() - 1));
}
static boolean isPalidrome(char[] test, int l, int r) {
if (l < r) {
if (test[l] == test[r]) {
return isPalidrome(test, l + 1, r - 1);
}
else {
return false;
}
}
return true;
}
}
By the way, the important lesson to take from all this is how to debug your program. In this case, printing your indices (the arguments that change from one call to the next) at the top of your recursive function will clearly show that they aren't doing what you expect.
I want to check the combination of values from data its exist or not. Below code works fine buts its looks inefficient. I am looking for some good solution of this problem.
public static void main(String args[]) {
Integer data[] = {
1, 2, 5, 1, 9, 3, 5, 3, 2
};
Integer combination[] = {
1, 3 ,2
};
System.out.println("Result: " + combinations(data, combination));
}
public static boolean combinations(Integer dataset[], Integer combination[]) {
boolean results[] = new boolean[combination.length];
Integer count = 0;
for (Integer comb : combination) {
for (Integer data : dataset) {
if (data.equals(comb)) {
results[count++] = true;
break;
}
}
}
for (Boolean result : results) {
if (!result) {
return false;
}
}
return true;
}
strong text
Looks like you just want to check if the combination is a subset of your data set...The order in which it appears in your data set is not important. Is that correct?
How big will be your data set? Is the data set created whenever it is required or is it maintained throughout?
If data set is large and is maintained throughout, it would be easier to search if you can maintain it sorted.
for (Integer comb : combination) {
if (Arrays.binarySearch(dataset, comb) < 0)
return false; //If any element is not found, return false
}
}
return true;
If you can keep the combination also sorted, you can further optimize it.
int loc = 0;
for (Integer comb : combination) {
loc = Arrays.binarySearch(dataset, loc, data.length, comb);
//Since both are sorted, u can be sure that next element will be
//after previous element match
if (loc < 0)
return false;
}
}
return true;
Even if you can't maintain a sorted array, one optimization u can do is to get rid of that boolean array and the for-loop at the bottom. Algorithm is as follows...
boolean isMatch = false;
for (Integer comb : combination) {
//We will be here in two condition -
// 1. first iteration or previous element was found in dataset.
// 2. Just set to false to check next element. Reset the flag
boolean isMatch = false;
for (Integer data : dataset) {
if (data.equals(comb)) {
//match found for the current combination element
isMatch = true;
break;
}
}
//This mean one of the combination element is not there. Break out.
if (!isMatch) break;
}
return isMatch;
Sort the dataset set which is complexity nlog(n). (Quick or merge sort maybe ? ) Then run binary search for every member of combination array over dataset. Binary search complexity log(n). When you do this for every member of combination array complexity will be nlog(n).
nlog(n) + nlog(n) = 2nlog(n) which is O(nlogn). This way your performance will be increase.
Code
public static boolean combinations(Integer dataset[], Integer combination[]) {
sort(dataset); // quick or insertion sort, nlogn
for (Integer comb : combination) { // n
if (!binarysearch(dataset, comb)) //logn
return false;
} //n*logn = nlogn
return true;} //2nlogn = O(nlogn)
You can change from array to ArrayList and use the containsAll method. not sure if it is efficient enough but will make your code shorter.
public static void main(String args[]) {
Integer data[] = {1, 2, 5, 1, 9, 3, 5, 3, 2};
Integer combination[] = {1,3 ,2};
System.out.println("Result: " + combinations(data, combination));
}
public static boolean combinations(Integer dataset[], Integer combination[]) {
List<Integer> data = Arrays.asList(dataset);
List<Integer> comb = Arrays.asList(combination);
return data.containsAll(comb);
}
Since your data consists of Integers which implements "Comparable", I would suggest you exploit that and construct a TreeSet and add all the data into it. You can then run a contains() to find if an element is present in the TreeSet or not.
TreeSet guarantees log(n) cost for each add, delete and contains.
Adding all elements(n) will cost you nlog(n).
Finding if 'm' elements are present will cost you mlog(n).
So I am having alot of difficulty conceptualizing answers for the following questions. I am not looking for answers but rather useful steps that I can take that will enable me to present the answers on my own. Note: to answer these questions I am given classes referenced, and a driver program. The questions are as follows:
Q.1 Implement a method replace for the ADT bag that replaces and returns any object currently in a bag with a
given object.
Q.2.Write a remove method to remove every instance of an element in an ArrayBag.
Q.3. Give at least two examples of a situation where a fixed bag is appropriate and two examples of a situation where a resizable bag is appropriate.
The following code is what I have started but am not sure if I am in right direction:
a.1 public T replace(T theItem) {
Random generator = new Random();
int randomPosition = generator.nextInt(numberOfEntries);
T result = null;
if (!isEmpty() && (randomPosition >= 0)) {
result = bag[randomPosition]; // Entry to remove
bag[randomPosition] = theItem; // Replace entry to remove with
// last entry
}
return result;
a.2 public void clear(T theItem) {
while (!this.isEmpty(ArrayBag))
this.remove();
a.3 not sure it should be related to coding examples or something else.
Additionally, the class for the ArrayBag is below for reference:
import java.util.Arrays;
import java.util.Random;
public final class ArrayBag<T> implements BagInterface<T> {
private final T[] bag;
private int numberOfEntries;
private boolean initialized = false;
private static final int DEFAULT_CAPACITY = 25;
private static final int MAX_CAPACITY = 10000;
/** Creates an empty bag whose initial capacity is 25. */
public ArrayBag() {
this(DEFAULT_CAPACITY);
} // end default constructor
/**
* Creates an empty bag having a given capacity.
*
* #param desiredCapacity
* The integer capacity desired.
*/
public ArrayBag(int desiredCapacity) {
if (desiredCapacity <= MAX_CAPACITY) {
// The cast is safe because the new array contains null entries
#SuppressWarnings("unchecked")
T[] tempBag = (T[]) new Object[desiredCapacity]; // Unchecked cast
bag = tempBag;
numberOfEntries = 0;
initialized = true;
} else
throw new IllegalStateException("Attempt to create a bag "
+ "whose capacity exceeds " + "allowed maximum.");
} // end constructor
/**
* Adds a new entry to this bag.
*
* #param newEntry
* The object to be added as a new entry.
* #return True if the addition is successful, or false if not.
* /
public boolean add(T newEntry) {
checkInitialization();
boolean result = true;
if (isArrayFull()) {
result = false;
} else { // Assertion: result is true here
bag[numberOfEntries] = newEntry;
numberOfEntries++;
} // end if
return result;
} // end add
/**
* Retrieves all entries that are in this bag.
*
* #return A newly allocated array of all the entries in this bag.
*/
public T[] toArray() {
checkInitialization();
// The cast is safe because the new array contains null entries.
#SuppressWarnings("unchecked")
T[] result = (T[]) new Object[numberOfEntries]; // Unchecked cast
for (int index = 0; index < numberOfEntries; index++) {
result[index] = bag[index];
} // end for
return result;
// Note: The body of this method could consist of one return statement,
// if you call Arrays.copyOf
} // end toArray
/**
* Sees whether this bag is empty.
*
* #return True if this bag is empty, or false if not.
*/
public boolean isEmpty() {
return numberOfEntries == 0;
} // end isEmpty
/**
* Gets the current number of entries in this bag.
*
* #return The integer number of entries currently in this bag.
*/
public int getCurrentSize() {
return numberOfEntries;
} // end getCurrentSize
/**
* Counts the number of times a given entry appears in this bag.
*
* #param anEntry
* The entry to be counted.
* #return The number of times anEntry appears in this ba.
*/
public int getFrequencyOf(T anEntry) {
checkInitialization();
int counter = 0;
for (int index = 0; index < numberOfEntries; index++) {
if (anEntry.equals(bag[index])) {
counter++;
} // end if
} // end for
return counter;
} // end getFrequencyOf
/**
* Tests whether this bag contains a given entry.
*
* #param anEntry
* The entry to locate.
* #return True if this bag contains anEntry, or false otherwise.
*/
public boolean contains(T anEntry) {
checkInitialization();
return getIndexOf(anEntry) > -1; // or >= 0
} // end contains
/** Removes all entries from this bag. */
public void clear() {
while (!this.isEmpty())
this.remove();
} // end clear
/**
* Removes one unspecified entry from this bag, if possible.
*
* #return Either the removed entry, if the removal was successful, or null.
*/
public T remove() {
checkInitialization();
T result = removeEntry(numberOfEntries - 1);
return result;
} // end remove
/**
* Removes one occurrence of a given entry from this bag.
*
* #param anEntry
* The entry to be removed.
* #return True if the removal was successful, or false if not.
*/
public boolean remove(T anEntry) {
checkInitialization();
int index = getIndexOf(anEntry);
T result = removeEntry(index);
return anEntry.equals(result);
} // end remove
public boolean removeRandom() {
Random generator = new Random();
int randomPosition = generator.nextInt(numberOfEntries);
T result = removeEntry(randomPosition);
if (result == null) {
return false;
} else {
return true;
}
}
#Override
public boolean equals(Object obj) {
if (obj instanceof ArrayBag) {
ArrayBag<T> otherArrayBag = (ArrayBag<T>) obj;
if (numberOfEntries == otherArrayBag.numberOfEntries) {
// I create new arrays so that I can manipulate them
// and it will not alter this.bag or otherArrayBag.bag
T[] currentBagTempArray = toArray();
T[] otherBagTempArray = otherArrayBag.toArray();
Arrays.sort(currentBagTempArray);
Arrays.sort(otherBagTempArray);
for (int i = 0; i < numberOfEntries; i++) {
if (!currentBagTempArray[i].equals(otherBagTempArray[i])) {
return false;
}
}
return true;
} else {
return false;
}
} else {
return false;
}
}
public ResizableArrayBag<T> createResizableArray() {
T[] currentBagContents = toArray();
ResizableArrayBag<T> newBag = new ResizableArrayBag<T>(currentBagContents);
return newBag;
}
// Returns true if the array bag is full, or false if not.
private boolean isArrayFull() {
return numberOfEntries >= bag.length;
} // end isArrayFull
// Locates a given entry within the array bag.
// Returns the index of the entry, if located,
// or -1 otherwise.
// Precondition: checkInitialization has been called.
private int getIndexOf(T anEntry) {
int where = -1;
boolean found = false;
int index = 0;
while (!found && (index < numberOfEntries)) {
if (anEntry.equals(bag[index])) {
found = true;
where = index;
} // end if
index++;
} // end while
// Assertion: If where > -1, anEntry is in the array bag, and it
// equals bag[where]; otherwise, anEntry is not in the array.
return where;
} // end getIndexOf
// Removes and returns the entry at a given index within the array.
// If no such entry exists, returns null.
// Precondition: 0 <= givenIndex < numberOfEntries.
// Precondition: checkInitialization has been called.
private T removeEntry(int givenIndex) {
T result = null;
if (!isEmpty() && (givenIndex >= 0)) {
result = bag[givenIndex]; // Entry to remove
int lastIndex = numberOfEntries - 1;
bag[givenIndex] = bag[lastIndex]; // Replace entry to remove with
// last entry
bag[lastIndex] = null; // Remove reference to last entry
numberOfEntries--;
} // end if
return result;
} // end removeEntry
// Throws an exception if this object is not initialized.
private void checkInitialization() {
if (!initialized)
throw new SecurityException(
"ArrayBag object is not initialized properly.");
} // end checkInitialization
} // end ArrayBag
Someone else implemented Bag using an Array at Bag Class Implementation in Java/Using Array . I only glanced at the code, so it may be a mixed Bag.
I'm assuming that Bag is like a Set, except in can store the same object more than once.
You would want to implement a private collection of some sort (perhaps an Array like above). Let's call it myBag.
Since you're using a generic type T, your Bag will only contain objects of type T.
For Q1, your replace() method might need to take two parameters: The object to be replaced (say findMe) and the object you're replacing it with (say replacement).
If your Bag can hold duplicates, then you will probably want to replace the first object that matches.
Rather than use Random(), you might need to go element by element through myBag, and replace the found element with the one you're replacing. You might want to throw an error if findMe is not found. So the method declaration might be something like:
public boolean replace(T findMe, T replacement)
and return true if findMe was found, false otherwise.
For Q2, you could create a while loop that removes the first element in myBag while the size of myBag was > 0.
For Q3, thre's no coding involved. This is a thinking question. In general, a fixed size Bag would be helpful when the size is known at the beginning will not change.
A resizable bag makes sense in more cases, where you don't know the size at the beginning and it is likely to shrink or grow, for example, a waiting list for a class.
I looked your starting code and class but I did not run it.
But I can say that you are in right direction.
For Q2, You should search the given element in array and remove the each one. Because question clearly says that "remove every instance of an element " Please check the getIndexOf() method. You can see how to search and element. If you find one matching remove it. Be careful if you remove and element while you are iterating over it. If you delete one element while you are iterating size will change. I offer you to store each matching on an array. After iteration use remove(index) method for each found element
Give at least two examples of a situation where a fixed bag is appropriate and two examples of a situation where a resizable bag is appropriate.
For this item you can add some explanation and some sample code or algorithm.
I can offer you two thing:
1. If the array is not getting full too fast fixed size is good. But if array is getting full too fast you should resize new array and copy all elements again and again. Overhead amount is important.
2. Amount of capacity is important. How you will decide initial size ? Big size or small size ? Think that
I hope this helps
everyone. I am currently having issue on doing the evaluation of postfix expression in Java and I think everything is alright except the output is not really correct. But never mind, please let me to post all the codes so that all of you can have a look on them. By the way, please be noted that all of you just need to concentrate on TestPalindrome class is enough because I never change the codes for the other classes except the class that I specified just now.
StackInterface defines all the methods that are available to ArrayStack class.
//There is no need to check this.
public interface StackInterface<T> {
/** Task: Adds a new entry to the top of the stack.
* #param newEntry an object to be added to the stack */
public void push(T newEntry);
/** Task: Removes and returns the stack誷 top entry.
* #return either the object at the top of the stack or, if the
* stack is empty before the operation, null */
public T pop();
/** Task: Retrieves the stack誷 top entry.
* #return either the object at the top of the stack or null if
* the stack is empty */
public T peek();
/** Task: Detects whether the stack is empty.
* #return true if the stack is empty */
public boolean isEmpty();
/** Task: Removes all entries from the stack */
public void clear();
} // end StackInterface
ArrayStack class that is nothing special.
//There is no need to check this.
public class ArrayStack<T> implements StackInterface<T> {
private T[] stack; // array of stack entries
private int topIndex; // index of top entry
private static final int DEFAULT_INITIAL_CAPACITY = 50;
public ArrayStack() {
this(DEFAULT_INITIAL_CAPACITY);
} // end default constructor
public ArrayStack(int initialCapacity) {
stack = (T[]) new Object[initialCapacity];
topIndex = -1;
} // end constructor
public void push(T newEntry) {
topIndex++;
if (topIndex >= stack.length) // if array is full,
doubleArray(); // expand array
stack[topIndex] = newEntry;
} // end push
public T peek() {
T top = null;
if (!isEmpty())
top = stack[topIndex];
return top;
} // end peek
public T pop() {
T top = null;
if (!isEmpty()) {
top = stack[topIndex];
stack[topIndex] = null;
topIndex--;
} // end if
return top;
} // end pop
public boolean isEmpty() {
return topIndex < 0;
} // end isEmpty
public void clear() {
} // end clear
/** Task: Doubles the size of the array of stack entries.
* Refer to Segment 5.18 */
private void doubleArray() {
T[] oldStack = stack; // get reference to array of stack entries
int oldSize = oldStack.length; // get max size of original array
stack = (T[]) new Object[2 * oldSize]; // double size of array
// copy entries from old array to new, bigger array
System.arraycopy(oldStack, 0, stack, 0, oldSize);
} // end doubleArray
} // end ArrayStack
The following class is TestPalindrome class.(The class name may sounds strange because the exercises that I did were all in the same class and I do not post the irrelevant codes in the class.)
import java.util.Scanner;
public class TestPalindrome {
public TestPalindrome() {
}
public static void main(String[] args) {
//P3Q2
StackInterface<Character> myStack = new ArrayStack<Character>();
Scanner scanner = new Scanner(System.in);
int result;
char resultInChar;
System.out.print("Please enter a postfix expresion : ");
String postfix = scanner.nextLine();
for(int i = 0; i < postfix.length(); i++)
{
char postfixChar = postfix.charAt(i);
if(Character.isDigit(postfixChar)) //If postfixChar is a digit, then it will be pushed into the stack.
{
myStack.push(postfixChar);
}
/*(For else statement) First operand will be popped as right operand and second
operand will be popped as left operand if postfixChar is operator such as + .
The calculation of both operands will be carried out based on the operator given.
After this the result of calculation will be pushed back into the stack and the
same things will happen again.*/
else
{
int firstOperand = Character.getNumericValue(myStack.pop()); //To get numeric value of the first character stored.
System.out.println("\nThe right operand : " + firstOperand);
int secondOperand = Character.getNumericValue(myStack.pop()); //To get numeric value of the second character stored.
System.out.println("The left operand : " + secondOperand);
switch(postfixChar)
{
case '+':
result = secondOperand + firstOperand;
System.out.println("The result is " + result);
resultInChar = (char)result; //Convert the result of calculation back to character data type so that it can be pushed into the stack.
System.out.println("Strange output : " + resultInChar); //Here is where the strange output occurred.
myStack.push(resultInChar);
break;
case '-':
result = secondOperand - firstOperand;
System.out.println("The result is " + result);
resultInChar = (char)result;
myStack.push(resultInChar);
break;
case '/':
result = secondOperand / firstOperand;
System.out.println("The result is " + result);
resultInChar = (char)result;
myStack.push(resultInChar);
break;
case '*':
result = secondOperand * firstOperand;
System.out.println("The result is " + result);
resultInChar = (char)result;
myStack.push(resultInChar);
break;
}
}
}
System.out.println("\nThe answer of " + postfix + " is " + Character.getNumericValue(myStack.pop())); //To get the final answer in the form of numeric value
}
}
Here is the attachment of the picture to show all the outputs of the program.
Please explain the wrong part as I really cannot figure out why this will happen since 1 + 1 = 2 and the ASCII code of 2 which is 50 should be displayed instead of the weird square symbol.Thanks because spending the valuable time to look into my problem.
You say:
Please explain the wrong part as I really cannot figure out why this
will happen since 1 + 1 = 2 and the ASCII code of 2 which is 50 should
be displayed instead of the weird square symbol.
Yes, 1 + 1 = 2. But if you cast it to a char, it will use ASCII value 2, and not 50. To do that, you should do something like:
resultCharIn = (char) ('0' + result);
In other words: '0' != 0.
However, this seems like a wrong approach, because: what if the result is greater than 9. You will need two characters. Maybe you should consider a different design?