Tore
asked on
Search for string in 2 dimensional string array
This relates to a previous question ( .. i forgot to get an answer before i closed it :( )
How do i search for a string in a 2 dim string array (column 0)
I have the following 2 dim string table. It is sorted by its first column.
I then thought i could use a Array.binarySearch (works fine for a one dimensional array) but i can't get my head around on how to do it on a 2 dim.
I need some expert advice.
import java.util.Arrays;
import java.util.Comparator;
public class TwoDimStringTable {
public static void main(String [] args) {
int i = 0;
String[][] sTabell = new String[8][2];
sTabell[0][0] = "Ola"; sTabell[0][1] = "Ola";
sTabell[1][0] = "var"; sTabell[1][1] = "kunne";
sTabell[2][0] = "fra"; sTabell[2][1] = "engelsk";
sTabell[3][0]= "Sandefjord"; sTabell[3][1]= "ei";
sTabell[4][0] = "Han"; sTabell[4][1] = "men";
sTabell[5][0] = "var"; sTabell[5][1] = "han";
sTabell[6][0] = "lettmatros"; sTabell[6][1] = "klarte";
sTabell[7][0] = "ombord!"; sTabell[7][1] = "seg";
for ( i = 0; i <= sTabell.length-1; i++) {
System.out.println(sTabell[i][0] + " " + sTabell[i][1]);
}
System.out.println(Arrays.deepToString(sTabell));
for (i = 0; i < sTabell.length; i++) {
Arrays.sort(sTabell[i]);
}
System.out.println(Arrays.deepToString(sTabell));
Arrays.sort(sTabell, new Comparator<String[]>() {
public int compare(String[] r1, String[] r2) {
return Arrays.compare(r1, r2);
}
});
System.out.println(Arrays.deepToString(sTabell));
for ( i = 0; i <= sTabell.length-1; i++) {
System.out.println("i = " + i + " " + sTabell[i][0] + " " + sTabell[i][1]);
// Question: how to get index of string "Sandefjord"
}
}
}
The problem with a binary search is that the array/collection must be sorted first. If, as you are, you are sorting by row, then the search token would have to be a whole row, not just a string in a row. What is your requirement – to find the indices of a complete string, or a partial string?
An iterative approach is probably right. Try
An iterative approach is probably right. Try
public static int[] findMatch(String[][] table, String pattern) {
int[] result = { -1, -1 };
for (int row = 0; result[0] < 0 && row < table.length; row++) {
for (int col = 0; result[1] < 0 && col < table[row].length; col++) {
if (table[row][col].matches(pattern)) {
result[0] = row;
result[1] = col;
}
}
}
return result;
}
ASKER
Thanks CEHJ
The main idea was to create the fastest serch, and binarySearch seems to be a quick one (hence the sorting).
Your suggestion is a sequential search so sorting gives no benefit.
When you say the search token needs to be the whole row, how will that look like in a binary search (to take advantage of the sorting).
The row in question holds "Sandefjord" and "ei" (column 0 an 1)
Appreciate your patience :)
The main idea was to create the fastest serch, and binarySearch seems to be a quick one (hence the sorting).
Your suggestion is a sequential search so sorting gives no benefit.
When you say the search token needs to be the whole row, how will that look like in a binary search (to take advantage of the sorting).
The row in question holds "Sandefjord" and "ei" (column 0 an 1)
Appreciate your patience :)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
not a real world problem yet, but what would you suggest for eg 5000 rows with names like this read from a database ?
You would run that search on the database
Multidimensional arrays - apart from maybe holding co-ordinates for graphic applications or some maths operations - seem to me to be a bit of a throwback to the days when less sophisticated tools were available. So although I don't have any more interesting insight than that, I am making this comment because, as has been said, it's not completely clear what it is you are trying to achieve - with database involvement or without. Why are you holding such a small amount of related data in this form ? I'm not getting involved in the database conversation, because I don't tread in that territory, but in OOP terms I would venture to say that a more conventional approach would be to hold this dimensioned data as objects with multiple fields of a class. What would an entry like :
Sandefjord ei
be doing floating around on its own ? Maybe I've missed something, or you have another particular aim in mind that I can't see.
Sandefjord ei
be doing floating around on its own ? Maybe I've missed something, or you have another particular aim in mind that I can't see.
ASKER
@both:
The above is more like a test on how to do it.
I.e. how to create and navigate in a 2dim string table/data structure and how to do a binary search.
What would be the most efficient data structure to do this in Java (i.e. not involving a database)?
The above is more like a test on how to do it.
I.e. how to create and navigate in a 2dim string table/data structure and how to do a binary search.
What would be the most efficient data structure to do this in Java (i.e. not involving a database)?
Well, as I've indicated above, a binary search is not really practicable. You would have to know the whole row to be able to call a binary search on it. If you knew the whole row, then you'd presumably also know what its position was…
ASKER
OK CEHJ
Thanks for the update. Appreciated :)
Case closed for now.
Thanks for the update. Appreciated :)
Case closed for now.
In case you inadvertently 'left early' again, I thought you might like to see my take on the OOP paradigm that I commented on, (money where my mouth was stuff) which holds individual pairs of your String array variables in single Objects (Twin, for want of a better class name), and maintains the array of those Twins in a separate class object called Creator (again for want of a better name).
Once the twins are created and stored in a HashSet, (so you can't have two identical entries), they can be sorted (in my approach, I decided to use an array). The first sort() will produce a first-field sort, and the second routine will do a subsort on the second field.
I've put both classes in the same file, to make it easier.
Once the twins are created and stored in a HashSet, (so you can't have two identical entries), they can be sorted (in my approach, I decided to use an array). The first sort() will produce a first-field sort, and the second routine will do a subsort on the second field.
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator ;
import java.util.HashSet ;
public class Creator {
public static void main(String [] args) {
int place = 0;
HashSet<Twin> ts = new HashSet<Twin>() ;
Twin twin = new Twin("Ola","var");ts.add(twin);
twin = new Twin("fra","Sandefjord");ts.add(twin);
twin = new Twin("Han","var");ts.add(twin);
twin = new Twin("lettmatros","ombord!");ts.add(twin);
twin = new Twin("Ola","kunne");ts.add(twin);
twin = new Twin("engelsk","ei");ts.add(twin);
twin = new Twin("klarte","han");ts.add(twin);
twin = new Twin("Ola","seg");ts.add(twin);
Iterator it = ts.iterator();
Twin[] twa = new Twin[ts.size()];
while(it.hasNext()){twa[place++]=(Twin)it.next();}
Arrays.sort(twa, new Comparator<Object>() {
public int compare(Object a, Object b) {
return (((Twin)a).first.compareToIgnoreCase(((Twin)b).first));
}
});
/*** Include the routine below if a subsort (i.e. on the second field) is required.
*/
Arrays.sort(twa, new Comparator<Object>() {
public int compare(Object a, Object b) {
if(((Twin)a).first.equals(((Twin)b).first)){
return (((Twin)a).second.compareToIgnoreCase(((Twin)b).second));
}
else{return ((Twin)a).first.compareToIgnoreCase(((Twin)b).first) ;}
}
});
for (int i = 0; i < twa.length; i++) {
System.out.println(twa[i].first+" "+twa[i].second) ;
}
}
}
class Twin {
public String first ;
public String second ;
public Twin(String f, String s){
this.first = f ;
this.second = s ;
}
public Twin(){}
}
I've put both classes in the same file, to make it easier.
ASKER
Thanks a lot krakatoa !
Very useful sample :)
I have to admit that I in the end ended up with a HashMap structure to solve my issue (as there was a few other additional things to include in the code )
Thanks !
Very useful sample :)
I have to admit that I in the end ended up with a HashMap structure to solve my issue (as there was a few other additional things to include in the code )
Thanks !
ok.
Open in new window
after the sort() of course.