The following code sorts through a dictionary of words in lexicographical order. The problem is that I cannot access the sorted array outside of the for loop. Well I think this is the problem. I have declared the array words in another method and returned it to a private variable within the same class. But after I sort the array and try to print it out, it just prints out the original array. I also want to mention that this sorting method does work as I have tested it in another class where everything was in the main method. So again I believe my problem has to do with returning the new sorted array. I also need to write a few lines of code within the method after the array is sorted and when I tried to return the array, using "return words;" I was unable to write this code.
public void insertionSort() {
int in, out;
for (out=1; out<nElems; out++){
String temp = words[out]; // remove marked item
in = out; // start shifting at out
while (in>0 && words[in-1].compareTo(temp)>0){ // until temp is lexicographically after after the word it is being compared to
words[in] = words[in-1]; // shifts word to next position in lexicographical order
--in;
}
words[in] = temp;
}
for(int i=0; i <words.length; i++)
System.out.println(words[i]);
I have declared the array words in another method
It sounds like you have declared two arrays: one inside the other method and an entirely separate one at class level that is being sorted. Make sure both methods are using the same array.
If you want them both to use the array declared at class level, don't declare a separate array in the other method. E.g., if you have String[] words = new String[10]; in the other method, change it to words = new String[10];. If you really need the nElems variable (i.e., if the sort method can't simply use words.length), make sure that variable is also not being redeclared and is being set to the correct value.
Alternatively, instead of depending on putting the data to be sorted in a particular array, your sort method would be more generally useful if it accepted any array to be sorted as a parameter:
public static void insertionSort(String[] words, int nElems) {
/* ... rest of method as before ... */
}
I've made that method static too, since it no longer depends on any instance fields.
Well, as I understand what you are saying, you are using a private variable at class level and that variable receives the words[] array items from a method... in that case:
Make sure the private variable at class level is an array named words.
Make the private variable (now named words) the same type as the words array received from the other method.
Because you are calling words from insertionSort() you need to acces the private variable values, you can't get the words[] array values from the other method, because that array is local to that method, so you must return it's values to some array varibale (the private variable that you must name words), so it's that variable that you must access.
Related
Here is what I have. I'm trying to add a name value to the ArrayList of type indexStruct and have no idea how to do that. Name is a String, any help would be great. Thanks!
import java.util.ArrayList;
public class Currentindex {
public void indexedWords(String currentWord, ArrayList <Indexstruct> currentIndex){
int convoMax=currentIndex.size();
int convoMin=0;
int placeHolder;
int strComp;
//pull words to skip that appear frequently in a typical conversation
while(convoMax>convoMin){ //binary search
placeHolder=(convoMin+convoMax)/2;
strComp=currentWord.compareToIgnoreCase(currentIndex.get(placeHolder).Word);
if(strComp==0){
currentIndex.add(placeHolder, Word); //<--Where problem occurs
break;
}
else if(strComp<0){
convoMax=placeHolder-1;
}
else{
convoMin=placeHolder+1;
}
}
//addterm(currentIndex);
System.out.println(currentIndex);
}
}
I'm trying to add a name value to the ArrayList of type indexStruct.
The specific ArrayList can only have elements added that are of type indexStruct.
This means, either they are:
objects of class indexStruct.
objects of a class extending indexStruct.
objects of a class implementing an interface called indexStruct.
The only way you could insert your string, is if there is a string field within the indexStruct Object.
You would create such an object, and assign the name. Then add this object to the arraylist.
currentIndex.add(placeHolder, Word);
The problem with the call currentIndex.add(placeHolder, Word); //<--Where problem occurs , is that the Word variable does not exist.
I am assuming that you compare the currentWord with the specific element at placeHolder, and then wish to re-insert the same Word Again when they are equal (ignoring case).
This should work if you change your line to:
currentIndex.add(placeHolder, currentIndex.get(placeHolder));
You would essentially be entering another instance of the same indexStruct object at the position placeHolder.
Also, I'd suggest you look into iterators or enhanced for loops which are optimized for iterating over ArrayLists.
See:
ArrayList.ListIterator(int index) vs ArrayList.get(int index)
http://www.deknight.com/java/enhanced-for-loop-in-java-5-0.html
You are using
ArrayList: Array List which can store objects of Indexstruct.
And you are trying to store indexstruct.word (Probably a String as I guess).
You are getting issues because of the type of Indexstruct.word is not compatible with ArrayList.
Try this
Add currentIndex.add(placeHolder, new Indexstruct(word));
OR alternatively set word to newly constructed Indexstruct object and then add that object.
Below is an example program from some notes on how to use the for loop in Java. I don't understand how the line element:arrayname works. Can someone briefly explain it, or provide a link to a page that does?
public class foreachloop {
public static void main (String [] args) {
int [] smallprimes= new int [3];
smallprimes[0]=2;
smallprimes[1]=3;
smallprimes[2]=5;
// for each loop
for (int element:smallprimes) {
System.out.println("smallprimes="+element);
}
}
}
It's another way to say: for each element in the array smallprimes.
It's equivalent to
for (int i=0; i< smallprimes.length; i++)
{
int element=smallprimes[i];
System.out.println("smallprimes="+element);
}
This is the so called enhanced for statement. It iterates over smallprimes and it turn assignes each element to the variable element.
See the Java Tutorial for details.
for(declaration : expression)
The two pieces of the for statement are:
declaration The newly declared block variable, of a type compatible with
the elements of the array you are accessing. This variable will be available
within the for block, and its value will be the same as the current array
element.
expression This must evaluate to the array you want to loop through.
This could be an array variable or a method call that returns an array. The
array can be any type: primitives, objects, even arrays of arrays.
That is not a constructor. for (int i : smallPrimes) declares an int i variable, scoped in the for loop.
The i variable is updated at the beginning of each iteration with a value from the array.
Since there are not constructors in your code snippet it seems you are confused with terminology.
There is public static method main() here. This method is an entry point to any java program. It is called by JVM on startup.
The first line creates 3 elements int array smallprimes. This actually allocates memory for 3 sequential int values. Then you put values to those array elements. Then you iterate over the array using for operator (not function!) and print the array elements.
I've got a problem.
I'm trying to compare a String and a int but can't seem to get working.
What am I doing wrong?
Getting this from Eclipse:
The type of the expression must be an array type but it resolved to List
int numberOfMoves;
List<String> highscoreLinkedList = new LinkedList<String>();
if (moves < Integer.parseInt(highscoreLinkedList[2])){
highscoreLinkedList[2] = Integer.toString(moves);
highscoreLinkedList[1] = name;
}
This is for a highscore textfile for a game I'm making. The String at index 2 is a number of moves and the int moves is also a number of moves.
You cannot access a list element using highscoreLinkedList[2] - that syntax is reserved for arrays. To access a list you have to use the get() method, i.e. highscoreLinkedList.get(2)
You are trying to treat list as an array, but the only way to access elements of the is through calling get() method. Your code does not compile.
Lists don't work the same way as arrays in Java. To access a certain element, you have to use the get() method, and to get the element, you need to use set(), like so:
// you have highscoreLinkedList[2], it should be:
highscoreLinkedList.get(2);
// you have highscoreLinkedList[2] = ..., it should be:
highscoreLinkedList.set(2, Integer.toString(moves));
You can see all of the methods for LinkedList here.
ArrayList<yellowPage> ob1 = new ArrayList<yellowPage>();
yellowPage thing = new yellowPage(100,100);
thing.calc(i,y,s3);
ob1.add(thing);
I stored some data in thing. How can I retrieve the value stored in ob1.thing?
If you know the index, you can do yellowPage
yellowPage yp = ob1.get(index);
Otherwise you need to iterate over the list.
Iterator<yellowPate> iter = ob1.iterator();
while(iter.hasNext())
{
yellowPage yp = iter.next();
yp.whateverYouwantGet();
}
Note: I just typed code here, there may be syntax errors.
int x=5;
int info=ob1.get(x).getInfo();
The above example will get whatever information you wanted from your yellow pages class (by using a getter method) at the 6th index (because 0 counts) of your array list ob1. This example assumes you want an integer from the yellow page. You will have to create a getter method and change the x to the index of the yellow page you want to retrieve information from.
An example getter method (which you should put in your yellow pages class) could look like this:
public int getInfo() { return z; }
In the above case z may be an instance variable in your yellow pages class, containing the information you're looking for. You will most probably have to change this to suit your own situation.
If you wanted to get information from all yellow pages stored in the array list then you will need to iterate through it as Chrandra Sekhar suggested
Use an Iterator object to do this.
ArrayList<yellowPage> ob1 = new ArrayList<yellowPage>();
yellowPage thing = new yellowPage(100,100);
thing.calc(i,y,s3);
ob1.add(thing);
yelloPage retrievedThing = null;
Iterator<yelloPage> i = ob1.iterator();
if(i.hasNext()){
retrievedThing = i.next();
}
You could have the data stored in thing (horribly named variable) simply returned from the calc method. That way you don't need to maintain state for prior calculations in subsequent calls. Otherwise you just need a getter type method on the YellowPage class.
public class YellowPage {
private int result;
public void calc(...) {
result = ...
}
public int getResult() {
return result;
}
}
Print the list and override toString method.
public String toString()
{
return (""+ a+b); //Here a and b are int fields declared in class
}
System.out.print(ob1);
Class ArrayList<E>
Syntax
ArrayList<Integer> list = new ArrayList<Integer>();
You replace "Integer" with the class that the list is of.
An application can increase the capacity of an ArrayList instance before adding a large number of elements using the ensureCapacity operation. This may reduce the amount of incremental reallocation.
E represents an Element, which could be any class.
ensureCapacity is used to ensure that the list has enough capacity to take in the new elements. It's called internally every time you add a new item to the list. As the name suggests, ArrayList uses an Array to store the items. So when the array is initialized, it's given an arbitrary length, say 10. Now once you've added 10 items, if you go to add the 11th item, it'll crash because it exceeds the arrays capacity. Hence, ensureCapacity is called (internally) to ensure that there's enough space. So if you were adding the 11th element, the array size might be, say, doubled, to 20.
I have a recursive algorithm which steps through a string, character by character, and parses it to create a tree-like structure. I want to be able to keep track of the character index the parser is currently at (for error messages as much as anything else) but am not keen on implementing something like a tuple to handle multiple returned types.
I tried using an Integer type, declared outside the method and passed into the recursive method, but because it's final, recursive call increments are "forgotten" when I return. (Because the increment of the Integer value makes the passed-by-value object reference point at a new object)
Is there a way to get something similar to work which won't pollute my code?
Since you've already discovered the pseudo-mutable integer "hack," how about this option:
Does it make sense for you to make a separate Parser class? If you do this, you can store the current state in a member variable. You probably need to think about how you're going to handle any thread safety issues, and it might be overkill for this particular application, but it might work for you.
It's kind of a hack, but sometimes I use an AtomicInteger, which is mutable, to do things like this. I've also seen cases where an int[] of size 1 is passed in.
The current solution I am using is:
int[] counter = {0};
and then pass it to the recursive algorithm:
public List<Thing> doIt (String aString, int[] counter) { ... }
and when I want to increment it:
counter[0]++;
Not super elegant, but it works...
Integers are immutable, which means that when you pass it as an argument it creates a copy rather than a reference to the same item. (explanation).
To get the behavior you're looking for, you can write your own class which is like Integer only mutable. Then, just pass it to the recursive function, it is incremented within the recursion, and when you access it again after the recursion is over it will still maintain its new values.
Edit: Note that using an int[] array is a variation on this method... In Java, arrays are also passed by reference rather than copied like primitives or immutable classes.
You could just use a static int class variable that gets incremented each time your doIt method is called.
You could also do:
private int recurse (int i) {
if (someConditionkeepOnGoing) {
i = recurse(i+1);
}
return i;
}
To be honest I would recode the function to make it a linear algorithm that uses a loop. This way you have no chance of running out of heap space if you are stepping through an extremely large string. Also, you would not need to have a the extra parameter just to keep track of the count.
This also would probably have the result of making the algorithm faster because it does not need to make a function call for every character.
Unless of course there is a specific reason it needs to be recursive.
One possibility I can think of is to store the count in a member variable of the class. This of course assumes that the public doIt method is only called by a single thread.
Another option is to refactor the public method to call a private helper method. The private method takes the list as a parameter and returns the count. For example:
public List<Thing> doIt(String aString) {
List<Thing> list = new ArrayList<Thing>();
int count = doItHelper(aString, list, 0);
// ...
return list;
}
private int doItHelper(String aString, List<Thing> list, int count) {
// ...
// do something that updates count
count = doItHelper(aString, list, count);
// ...
return count;
}
This assumes that you can do the error handling in the public doIt method, since the count variable isn't actually passed back to the caller. If you need to do that, you could of course throw an exception:
public List<Thing> doIt(String aString) throws SomeCustomException {
List<Thing> list = new ArrayList<Thing>();
int count = doItHelper(aString, list, 0);
// ...
if (someErrorOccurred) {
throw new SomeCustomException("Error occurred at chracter index " + count, count);
}
return list;
}
It's difficult to know whether that will help without knowing more about how your algorithm actually works.