Brock Harris
Brock Harris

Reputation: 29

Search array for value containing all characters(in any order) and return value

I've searched high and low and finally have to ask.

I have an array containing, for example, ["123456","132457", "468591", ... ].

I have a string with a value of "46891".

How do I search through the array and find the object that contains all the characters from my string value? For example the object with "468591" contains all the digits from my string value even though it's not an exact match because there's an added "5" between the "8" and "9".

My initial thought was to split the string into its own array of numbers (i.e. ["4","6","8","9","1"] ), then to search through the array for objects containing the number, to create a new array from it, and to keep whittling it down until I have just one remaining.

Upvotes: 1

Views: 654

Answers (8)

MadConan
MadConan

Reputation: 3767

This sorts the char[]'s of the search string and the and the string to search on. Pretty sure (?) this is O(n logn) vs O(n^2) without sorting.

private static boolean contains(String searchMe, String searchOn){
    char[] sm = searchMe.toCharArray();
    Arrays.sort(sm);
    char[] so = searchOn.toCharArray();
    Arrays.sort(so);
    boolean found = false;
    for(int i = 0; i<so.length; i++){
        found = false; // necessary to reset 'found' on subsequent searches
        for(int j=0; j<sm.length; j++){ 
            if(sm[j] == so[i]){
                // Match! Break to the next char of the search string.
                found = true;
                break;
            }else if(sm[j] > so[i]){ // No need to continue because they are sorted.
                break;
            }
        }
        if(!found){
            // We can quit here because the arrays are sorted.
            // I know if I did not find a match of the current character
            // for so in sm, then no other characters will match because they are
            // sorted. 
            break;
        }
    }
    return found;
}

public static void main(String[] args0){
    String value = "12345";

    String[] testValues = { "34523452346", "1112", "1122009988776655443322",
                              "54321","7172839405","9495929193"};
    System.out.println("\n     Search where order does not matter.");
    for(String s : testValues){
        System.out.println("     Does " + s + " contain " + value + "? " + contains(s , value));
    }
}

And the results

 Search where order does not matter.
 Does 34523452346 contain 12345? false
 Does 1112 contain 12345? false
 Does 1122009988776655443322 contain 12345? true
 Does 54321 contain 12345? true
 Does 7172839405 contain 12345? true
 Does 9495929193 contain 12345? true

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726639

Since this is likely a learning assignment, I'll give you an idea instead of an implementation.

Start by defining a function that takes two strings, and returns true if the first one contains all characters of the second in any order, and false otherwise. It should looks like this:

boolean containsAllCharsInAnyOrder(String str, String chars) {
    ...
}

Inside the function set up a loop that picks characters ch from the chars string one by one, and then uses str.indexOf(ch) to see if the character is present in the string. If the index is non-negative, continue; otherwise, return false.

If the loop finishes without returning, you know that all characters from chars are present in src, so you can return true.

With this function in hand, set up another loop in your main function to go through elements of the array, and call containsAllCharsInAnyOrder on each one in turn.

Upvotes: 3

Shamse Alam
Shamse Alam

Reputation: 1315

try this

public static void main(String args[]) {
    String[] array = {"123456", "132457", "468591"};
    String search = "46891";
    for (String element : array) {
        boolean isPresent = true;
        for (int index = 0; index < search.length(); index++) {
            if(element.indexOf(search.charAt(index)) == -1){
                isPresent = false;
                break;
            }
        }

        if(isPresent)
            System.out.println("Element "+ element + " Contains Serach String");
        else
            System.out.println("Element "+ element + " Does not Contains Serach String");
    }
}

Upvotes: 0

Vivin Paliath
Vivin Paliath

Reputation: 95528

I think you can use sets for this.

List<String> result = new ArrayList<>();
Set<String> chars = new HashSet<>(Arrays.asList(str.split(""));
for(String string : stringList) {
    Set<String> stringListChars = new HashSet<>(Arrays.asList(string.split(""));

    if(chars.containsAll(stringListChars)) {
       result.add(string);
    }
}

There is a caveat here; it doesn't work as you would expect for repeated characters and you haven't specified how you want to handle that (for example, 1154 compared against 154 will be considered a positive match). If you do want to take into account repeated characters and you want to make sure that they exist in the other string, you can use a List instead of a Set:

List<String> result = new ArrayList<>();
List<String> chars = Arrays.asList(str.split(""));
for(String string : stringList) {
    List<String> stringListChars = Arrays.asList(string.split("");

    if(chars.containsAll(stringListChars)) {
       result.add(string);
    }
}

Upvotes: 2

quazzieclodo
quazzieclodo

Reputation: 831

You could do this with the ArrayList containsAll method along with asList:

ArrayList<Character> lookingForChars = new ArrayList<Character>(Arrays.asList(lookingForString.toCharArray()));

for (String toSearchString : array) {

    ArrayList<Character> toSearchChars = new ArrayList<Character>(Arrays.asList(toSearchString.toCharArray));
    if (toSearchChars.containsAll(lookingForChars)) {
        System.out.println("Match Found!");
    }
}

Upvotes: 1

Orel Eraki
Orel Eraki

Reputation: 12196

This is more tricky then a straigt-forward solution.
The are better algorithms but here one easy to implement and understand.

Ways of solving:

  1. Go through every char at your given string and check if it at the given arrray.
  2. Collect list for every string from the selected array containing the given char.
  3. Check if no other char to check.
    If there is, Perform A again but on the collected list(result list).
    Else, Return all possible matches.

Upvotes: 0

Алексей
Алексей

Reputation: 1847

Your initial idea was good start, so what you can do is to create not an array but set, then using Guava Sets#powerSet method to create all possible subsets filter only those that have "46891".length mebers, convert each set into String and look those strings in the original array :)

Upvotes: 1

Joffrey
Joffrey

Reputation: 37720

You can use String#chartAt() in a nested for loop to compare your string with each of the array's elements.

This method would help you check whether a character is contained in both strings.

Upvotes: 0

Related Questions