2
\$\begingroup\$

I'm looking for an lib which can search an array of strings with multible search-strings (array). I want to get an int-array of all indexes/matches.

private int[] getIndexArray(String[] pArray, String[] pSearchStrings) {
    int[] indexes = new int[0];
    for (String str : pArray) {
        if (ArrayUtils.contains(pSearchStrings, str))
            indexes = ArrayUtils.add(indexes, ArrayUtils.indexOf(pArray, str));
    }
    return indexes;
}

Is there a better way of doing it?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

Try this:

private static int[] getIndexArray(String[] pArray, String[] pSearchStrings) {
    //There can only be as many indices as there are search terms, right? So:
    int [] indexes = new int [pSearchStrings.length];
    int i = 0;
    for (String str : pArray) {
            if (ArrayUtils.contains(pSearchStrings, str))
            indexes[i++] = ArrayUtils.indexOf(pArray, str);
    }
    return indexes;
}

I haven't tested it, so I dunno if it works, but your code makes a new array every time through the loop (which isn't that big of a deal, but still).

\$\endgroup\$
1
\$\begingroup\$

If you use pSearchStrings[] for all pArray[], you can transform pSearchStrings in a Pattern and use matcher method to avoid to load each time ArrayUtils.contains(..)

EDIT

private static int[] getIndexArray(String[] pArray, String[] pSearchStrings) {
    StringBuilder sb = new StringBuilder((int) estimateSizeOfSearchStrings +16);
    for (String searh : pSearchStrings) {
         sb.append(".*");
         sb.append(search)
         sb.append(".*|");
    }
    Pattern patt = Pattern.compile(sb.toString().subString(0,sb.length() -1);
    // If pSearchStrings are always the same, you can put static 'patt' outside this method
    // Or pass pre-compiled 'patt' as a parameter.
    int [] indexes = new int [pSearchStrings.length];
    int i = 0;
    for (String str : pArray) {
            if (patt.matcher(str).find())
            indexes[i++] = ArrayUtils.indexOf(pArray, str);
    }
    return indexes;
}
\$\endgroup\$
4
  • \$\begingroup\$ Interesting point of view. But is it really a better way of checking to create a pattern and check the pattern instead of calling ArrayUtils.contains(..). Both methods will run in O(n), but the creation of the pattern will cost performance and memory. \$\endgroup\$ Commented Aug 1, 2013 at 8:41
  • \$\begingroup\$ @d.poellath As I wrote in comment, if you can put pattin a static field outside the method, or have determined Pattern to pass as parameter, it certainly will give more maintanble code. I'm not certain that a foreach with ArrayUtils.indexOf() will be needed if you use a fr(int i = 0, n = pArray.length; ...) \$\endgroup\$ Commented Aug 1, 2013 at 10:15
  • \$\begingroup\$ I have to correct my comment before. The methods both will need O(n*m), because of the two arrays. In your method the search-array of size m will be transformed to an string of sitze m*(size(searchStr)). there is no really time saving. especially because the you need to create a pattern for every different search array (and store for reuse). or do i miss something? \$\endgroup\$ Commented Aug 1, 2013 at 11:37
  • \$\begingroup\$ @d.poellath Usign pattern(s) is useful only if you can built it(them) at the begining, and know all matching cases ; then pass it(them) as a parameter. If getIndexArray is uses three or more times on big []pArray, it may be worst to test the two methods . But I guess the gain is less than 1%, compile tools are too powerful. \$\endgroup\$ Commented Aug 1, 2013 at 12:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.