What is the code that goes into: void changeElem(String oldStr, String newStr)?
I have a driver's class with:
public static void main(String[] args) {
// create empty list
SimpleLinkedList list = new SimpleLinkedList(null);
// add some elements in the list in
// reverse order so that list is sorted
list.addElement("W");
list.addElement("T");
list.addElement("P");
list.addElement("L");
list.addElement("K");
list.addElement("B");
list.printList();
System.out.println("change W to X");
list.changeElem("W", "X");
}
I am supposed to make a new method called “changeElem” in another class where
void changeElem(String oldStr, String newStr) but I am not sure how.
The answer by manikanta is right; however, changeElement(List list, String string, String replacement) requires you to pass the List as a parameter, which means you can't use it in the context list.changeElement("W", "X").
I'm assuming SimpleLinkedList is a Java class that you have implemented.
To use the method as list.changeElement("W", "X") instead of changeElement(list, "W", "X"), you need to add the method changeElement to the SimpleLinkedList class (which I think is actually your question).
Since actual implementation of the class isn't known, something like this:
public class SimpleLinkedList {
public void add(String str) {
//This should be an existing method, for example
}
//Assuming this is the implementation
private class Node {
String data;
Node nextNode;
}
private Node firstNode; //Should be set/unset in your add/remove method
//New method. To keep the order of your list, iterate and replace individually
public void changeElement(String str, String replacement) {
for (Node n = firstNode; n != null; n = n.nextNode) {
if (str.equals(n.data)) {
n.data = replacement;
break; //If you want to replace only one instance
}
}
}
}
Also, when in doubt: Look at Java's source code. What you basically want to do is find the place where str is and then replace it.
That's almost the Java LinkedList#indexOf method, except instead of returning index when you find str, you're replacing it. Java's LinkedList#indexOf() implementation.
We just have to add the replacement string at your intended location and then we should remove the unwanted string.
public static void main(String[] args) {
/* // create empty list
* LinkedList list = new LinkedList(null);
*/
LinkedList listLinked = new LinkedList<String>();
// add some elements in the list in
// reverse order so that list is sorted
listLinked.add("W");
listLinked.add("T");
listLinked.add("P");
listLinked.add("L");
listLinked.add("K");
listLinked.add("B");
changeElement(listLinked, "W", "X");
System.out.println(listLinked);
}
private static void changeElement(
List list, String string, String replacement) {
if (list.contains(string)) {
// adding the replacement
list.add(list.indexOf(string), replacement);
// removing the unwanted
list.remove(string);
} else {
System.out.println("Element not found to replace");
}
}
Assuming your SimpleLinkedList implements the List interface and is at least Java 8:
private static void changeElement(
List<String> list, String string, String replacement) {
list.replaceAll(s -> s.equals(string) ? replacement : s);
}
Of course you could call this 'Util' method from your SimpleLinkedList passing itself as the first argument.
Related
I used following method to add my data to ArrayList.
ArrayList<Word> wordList = new ArrayList<Word>();
Word word = new Word();
word.set_id(id);
word.setWord(word);
word.setDefinition(definition);
wordList.add(word);
After the add some data, I want find the position of the any id which I want find in ArrayList.
Already I have tried following method to get position by id. But it isn't work.
int position = wordList.indexOf(id);
and
int position = wordList.lastIndexOf(id);
Both codes always generated "position = -1" as a result. How can I do that?
Edited
This is the code of the Word.java class. How can I implement equal method?
public class Word {
private String _id, word, definition, favourite, usage;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public String getDefinition() {
return definition;
}
public void setDefinition(String definition) {
this.definition = definition;
}
public String getFavourite() {
return favourite;
}
public void setFavourite(String favourite) {
this.favourite = favourite;
}
public String getUsage() {
return usage;
}
public void setUsage(String usage) {
this.usage = usage;
}
}
indexOf is trying to compare Word objects. Your list doesn't contain ids as the elements, so you get -1.
You need to use a loop and search the list.
int id = 3;
int position = -1;
for (int i = 0; i < wordlist.size(); i++) {
if (wordlist.get(i).getId() == id) {
position = i;
// break; // uncomment to get the first instance
}
}
Note: this will search the whole list to find the last index of that id. So if there are duplicates and you only want the first one (or stop the loop as soon as you find what you want) add a break in the if statement.
Implement equals method in the "Word" object. Inside equals method you can apply equals only to id field.
Create a new Word object with that id and pass that object in indexOf. Don't pass the id in the indexOf. Pass the new of existing Word object with the required id.
Then indexOf will return the valid index of this word object.
For searching the object in a list. you need to override equals method in your Word class. otherwise you will get -1. because indexOf internally used equals method to search the element in list.
The class inside your list should implement hascode() and equals() in order to have indexOf() that works.
The tester class is:
public class SentenceWithReverseTester
{
public static void main(String[] args)
{
String[] list = new String[]{"aba",
"Madam, I'm Adam",
"nut",
"A man, a plan, a canal, Panama",
"wonderful",
"Go hang a salami, I'm a lasagna hog",
"race car",
"1",
"",
"zero",
"#!:"} ;
for (String line : list) {
SentenceWithReverse sentence = new SentenceWithReverse(line) ;
sentence.reverse() ;
System.out.println(line + " reversed becomes........") ;
System.out.println(sentence.toString()) ;
System.out.println("----------------------------") ;
}
}
}
And for the reverse method I have:
public void reverse()
{
String s = super.toString();
if(s.length() > 0)
{
String first = s.substring(0,1);
String remaining = s.substring(1, s.length());
SentenceWithReverse shorter = new SentenceWithReverse(remaining);
shorter.reverse();
System.out.println(shorter + first);
}
}
I'm not getting the result I want, and I'm not sure what I'm doing wrong here.
You should make reverse() actually return a String, rather than void, so that you can use the result of the reversal. So change void to String in the method's declaration. Then you'll need a couple of return statements inside the method - one for the base case and one for the recursive case.
In the recursive case, the return statement will be something like
return shorter.reverse() + first;
that is, you take the reverse of the shorter sentence, and put the first character back at the end.
In the base case, that is, where the input to the method is "", you can just write
return "";
I'll leave it to you to figure out where to insert these two return statements, within the logic of your method. Good luck.
You're not assigning any member fields in your reverse method. You don't show what fields you have, but I would guess you have a single String field that is returned from toString. You should assign the shorter + first to it where you have the System.out.println call.
Please give me in any tips with my class.
I want to make a return statement that will return the first word
in my wordList.
import java.util.ArrayList ;
public class WordList {
private ArrayList<String> theWordList = new ArrayList<String>();
public void addWord(String s) {
theWordList.add(s);
}
/* Check point 5: complete the method below */
public String getFirst() {
/* Replace the return statement bel
ow with a statement
* that returns
* the first word of theWordList (the word at index 0).
* Hint: use the ArrayList method "get".
* If there is no first word (theWordList has no words in it),
* "
-
" should be returned.
*/
return "junk";
}
You can make it this way
public String getFirst() {
if(this.theWordList!=null && this.theWordList.size() > 0)
return this.theWordList.get(0);
return "-";
}
Note : I have returned - (hyphen) when there is no first word in the list or the word list is null (which is not going to happen anyway since it is instantiated earlier)
return theWordList.get(0);
Be sure theWordList is not empty anyway
Make your get function as :
public ArrayList<String> getFirst() {
return this.theWordList;
}
And write a main () AS :
public static void main(String args[]){
WordList w=new WordList();
w.addWord("subash");
//Blah
//blahhhhh ....
System.out.println(w.getFirst().get(0));
}
How can I implement binary search to find a string with a particular prefix in generic array (which in this case will be a string[]). I tried compareTo but that wouldn't help because i have to use a string prefix. eg String prefix "Bi" bill, bilards ...etc..
Implement the following method to return all strings in an alphabetically sorted array that start with a given prefix. For instance, given a prefix “bi”, the returned strings are ”Bill Clinton”, ”Bill Gates”, and ”Bill Joy”. Note that all string comparisons should be case INSENSITIVE. The strings in the returned list must be in the order in which they appear in the array. Your implementation must be based on binary search, and must run in worst case O(log n+k) time, where n is the length of the array, and k is the number of matching strings. Assume that the array has no duplicate entries. If there are no matches, you may either return null, or an empty array list.
You may use the following String methods (in addition to any others you may recall):
boolean startsWith(String s)
int compareTo(String s)
int compareToIgnoreCase(String s)
String toLowerCase(String s)
String toUpperCase(String s)
(As for ArrayList, you only need to use the add method to add an item to the end of the array list.)
You may write helper methods (with full implementation) as necessary. You may not call any method that you have not implemented yourself
public static <T extends Comparable<T>> ArrayList prefixMatch(T[] list, String prefix) {
ArrayList<T> result = new ArrayList<T>();
int lo = 0;
int hi = list.length - 1;
while(lo <= hi) {
int mid = (hi + lo) / 2;
list[mid].startsWith(prefix) ? 0 : list[mid].compareTo((T) prefix));
}
return null;
}
You can use default binary search with custom comparator as your base, and then work our range by your self. I think the right algorithm would be:
Perform binary search on given array. Use comparator which checks only for prefix.
As result you'll get index of string which starts with your prefix
Walk to the left to find first string which matches prefix, remember position.
Walk to the right to find first string which matches prefix, remember position.
Copy elements from range start to range end from original array. That will be your desired array of all elements with prefix match condition.
Below is implementation in java. It works in happy case scenario but will crash if(I left those checks out to make code look simple):
No strings with given prefix exist in original array
There are string with length less then prefix length
Also if you need binary search implementation you could check source of Arrays.binarySearch
public class PrefixMatch {
public static void main(String[] args) {
final String[] prefixMathces = prefixMatch(new String[] { "Abc", "Abcd", "Qwerty", "Pre1", "Pre2", "Pre3", "Xyz", "Zzz" }, "pre");
for (int i = 0; i < prefixMathces.length; i++)
System.out.println(prefixMathces[i]);
}
public static String[] prefixMatch(final String[] array, final String prefix) {
final Comparator<String> PREFIX_COMPARATOR = new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
return o1.substring(0, prefix.length()).compareToIgnoreCase(o2);
}
};
final int randomIndex = Arrays.binarySearch(array, prefix, PREFIX_COMPARATOR);
int rangeStarts = randomIndex, rangeEnds = randomIndex;
while (rangeStarts > -1 && array[rangeStarts].toLowerCase().startsWith(prefix.toLowerCase()))
rangeStarts--;
while (rangeEnds < array.length && array[rangeEnds].toLowerCase().startsWith(prefix.toLowerCase()))
rangeEnds++;
return Arrays.copyOfRange(array, rangeStarts + 1, rangeEnds);
}
}
I assume that you currently have something like this? :
arrayElement.compareTo(prefix)
If so, you can change it to look like this:
arrayElement.startsWith(prefix) ? 0 : arrayElement.compareTo(prefix)
I suggest looking into the API code for this. There is an Arrays class that you can check out in the java.lang package and learn from there.
Working on a similar problem right now. I believe pseudo code will go something like yours. I created a pojo class Song. A song is made up up three strings artist,title, and lyrics.
When you create a song object you get :
// Artist Title Lyrics..
Song a = ["Farmer Brown", "Oh' Mcdonalad", "Oh'mcdonal had a farm eh i oh i oh"]
public class Song implements Comparable<Song> {
private String _artist;
private String _lyrics;
private String _title;
// constructor
public Song(String artist, String title, String lyrics) {
this._artist = artist;
this._title = title;
this._lyrics = lyrics;
}
public String getArtist() {
return _artist;
}
public String getLyrics() {
return _lyrics;
}
public String getTitle() {
return _title;
}
public String toString() {
String s = _artist + ", \"" + _title + "\"";
return s;
}
//This compare two song objects
public int compareTo(Song song) {
String currentSong = song.toString();
int x = currentSong.compareToIgnoreCase(this.toString());
return x;
}
This is your method here that will take in the array of songs and your prefix and use the compare method to see if they match. If they match the compareTo method returns a 0. If you get a 0 then you know you have found your song so return the arrayOfSongs[index where song is found].
I have not coded up my search yet but I modified yours to match my code. I have not tested it yet. I don't think you even need a compareTo method but you can use it. Also for scaling the binary search should return a list of songs that might match as you might have multiple songs that start with "xyz" . Kind of when you start searching on google with prefix "do" you get a drop down of "dog, donut,double" which gives the user something to choose like a search engine.
public static ArrayList<Song> search (String[] arrayOfSongs , String enteredPrefix) {
ArrayList<Song> listOfMatches = new ArrayList<Song>;
int mid;
int lo = 0;
int hi = arrayOfSongs.length - 1;
while(lo <= hi)
{
mid = (hi + lo) / 2;
if(arrayOfSongs[mid].startsWith(enteredPrefix))
{
System.out.println("Found a match, adding to list");
listOfMatches.add(arrayOfSongs[mid]);
}
}
return listOfMatches;
}
Once you have a listOfMatches of possible suspects of the song you want you can use the compareTo method in some way.
public static void printFib(List<Integer> fib){
JTextArea text = new JTextArea();
for(Iterator<Integer> it = fib.iterator(); it.hasNext(); it.next() ){
text.append(it.toString());
text.append("\n");
}
JOptionPane.showMessageDialog(null,text);
}
How can I modify this to have it actually print the data contents and not the pointer address?
Do you really need an interator?
for (Integer i : fib)
{
text.append(i.toString());
text.append("\n");
}
If for some reason you need an iterator for something else, then you use it as:
Iterator<Integer> it = fib.iterator();
while (it.hasNext())
{
text.append(it.next().toString());
text.append("\n");
}
Edit: To summarize comments below; Rather than getting the Integer the iterator contained via it.next(), The OP was calling the iterator's toString() method and receiving a String containing the hex representation of the iterator's hash code.
Why are you doing it like that anyway?
for (Integer i : fib) {
text.append(i.toString());
text.append("\n");
}
Anyway, you're appending it (not it.next()). You're printing the iterator, not what's being iterated.
If I were doing it I'd probably write the method like this; YMMV:
public static void printFib(List<Integer> fib){
StringBuilder sb = new StringBuilder();
for (Integer i : fib) {
sb.append(i).append("\n");
}
JTextArea text = new JTextArea(sb.toString());
JOptionPane.showMessageDialog(null, text);
}
Actually, I'd probably do it like this, but they make special little buses for people like me:
public static void main(String[] args) {
List<Integer> fib = Arrays.asList(1, 2, 3);
display(buildFibOutput(fib));
}
private static void display(String s){
JTextArea text = new JTextArea(s);
JOptionPane.showMessageDialog(null, text);
}
private static String buildFibOutput(List<Integer> fib) {
StringBuilder sb = new StringBuilder();
for (Integer i : fib) {
sb.append(i).append("\n");
}
return sb.toString();
}
Assuming you want to use an iterator, you need to get the next value and print that, not the iterator itslef, which you are doing. Something like
//create an iterator, then
while (it.hasNext()) {
text.append(it.next());
...
}
While you can use a for loop, I think a while loop is probably simpler to understand in the context...
try this:
public static void printFib(List<Integer> fib){
JTextArea text = new JTextArea();
for(Integer it : fib){
text.append(it.toString());
text.append("\n");
}
JOptionPane.showMessageDialog(null,text);
}
your problem is that text is JTextArea instance. After passing it to JOptionPane.showMessageDialo(null,text); over text is called method toString(), which is delivered by Object super type. To solve this problem, you need to pass to that method the content of that text instance. To do that just call method getText(), and should work.
In addition to improve your code:
I no aware how method append, works but a good practice is to use StringBuilder class to reduce the operation over immutable String objects. As the are immutable, when you need a concatenation of those you are really creating new one object, so each pass of loop will create new object. Another thing is that you are using obsolete approach, for List iteration. Since foreach loop has been introduced in Java, it should be used instead that for pattern you have implemented. The for each loop can be used over all elements, that implements interface Iterable, so improved version of your code would look like:
public static <T> void print(Iterable<T> iterable){
if(iterator == null) { //We throw an exception if method can not operater
throw new IllegelArgumentException("The argument iterable must not be null".
}
StringBuilder sb = new StringBuilder();
for(T element : iterable) { //for each loop
sb.apppend(String.valueOf(element));
sb.append("\n");
}
JOptionPane.showMessageDialog(null,sb.toString());
}
In addition the method is generic.