3

I have an array which contains bunch of strings, and I would like to find all of the possible combinations no matter how it's being sorted that match with given string/word.

$dictionary = ['flow', 'stack', 'stackover', 'over', 'code'];

input: stackoverflow
output:
#1 -> ['stack', 'over', 'flow']
#2 -> ['stackover', 'flow']

What I've tried is, I need to exclude the array's element which doesn't contain in an input string, then tried to match every single merged element with it but I'm not sure and get stuck with this. Can anyone help me to figure the way out of this? thank you in advance, here are my code so far

<?php

$dict = ['flow', 'stack', 'stackover', 'over', 'code'];
$word = 'stackoverflow';

$dictHas = [];
foreach ($dict as $w) {
    if (strpos($word, $w) !== false) {
      $dictHas[] = $w;
    }
}

$result = [];
foreach ($dictHas as $el) {
    foreach ($dictHas as $wo) {
        $merge = $el . $wo;
        if ($merge == $word) {

        } elseif ((strpos($word, $merge) !== false) {

        }
    }
}

print_r($result);
2
  • What should happen if the input string contains a substring that is not present in dictionary? What should happen if the input string contains single word from dictionary multiple times? Commented Sep 22, 2019 at 12:06
  • @MichalHynčica this case assumes that all of the substring present in dictionary and each of the dictionary's member is unique, which means no duplication Commented Sep 22, 2019 at 12:16

1 Answer 1

3

For problems like this you want to use backtracking

function splitString($string, $dict)
{
    $result = [];
    //if the string is already empty return empty array
    if (empty($string)) {
        return $result;
    }

    foreach ($dict as $idx => $term) {
        if (strpos($string, $term) === 0) {
            //if the term is at the start of string

            //get the rest of string
            $substr = substr($string, strlen($term));

            //if all of string has been processed return only current term
            if (empty($substr)) {
                return [[$term]];
            }
            //get the dictionary without used term
            $subDict = $dict;
            unset($subDict[$idx]);

            //get results of splitting the rest of string
            $sub = splitString($substr, $subDict);
            //merge them with current term
            if (!empty($sub)) {
                foreach ($sub as $subResult) {
                    $result[] = array_merge([$term], $subResult);
                }
            }
        }
    }

    return $result;
}

$input = "stackoverflow";
$dict = ['flow', 'stack', 'stackover', 'over', 'code'];

$output = splitString($input, $dict);
Sign up to request clarification or add additional context in comments.

2 Comments

I'm impressed this answer came so quick with this excellent and in simple way, great explanation and +1 for the reference you mentioned there. Thank you
I've slightly edited the function because it was giving wrong result for "stackoveroverflow".

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.