Блог пользователя K_B_C_S

Автор K_B_C_S, история, 6 лет назад, По-английски

Check if a master string contains all the strings given in a list. Also, strings should not overlap.

example:

1) "indiaismycountry" is a master string which contains all strings {"is", "country, india"}.

2) "animal" is a master string which doesn't contains {"an", "animal"}.

This question not form any running contest. I is asked in a interview.

Any solution or useful link will be helpful.

Thanks in advance!

  • Проголосовать: нравится
  • 0
  • Проголосовать: не нравится

»
6 лет назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

Auto comment: topic has been updated by K_B_C_S (previous revision, new revision, compare).

»
6 лет назад, # |
Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

First of all sort the list strings in decreasing order according to length and the check for every string one by one and check two conditions ,

  1. If string is not found in master string then return "false"

  2. If string is found in master string then (replace it with *) them from master string.

If all the string satisfied condition 2nd return "True"

  • »
    »
    6 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    can you explain your approach with "monkeyoumonkeyuo" as master string and {"monkey", "you"} as list of string?

    • »
      »
      »
      6 лет назад, # ^ |
      Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

      first search monkey , monkey is in master string then replace monkey (replace which monkey which does not contain any other string) from master string the master string becomes (monkeyou******uo).

      Then search you in master string it is found in master string) so answer is TRUE.

      UPD : don't delete , replace it with ******

    • »
      »
      »
      6 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      This can be check but time limit exceeded.

  • »
    »
    6 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

    This is wrong. Simple example: baaba, {"a", "baab"}. After finding and removing a, the string will become baba, and the last one string is left, however, it could be found if we searched for baab first.

    • »
      »
      »
      6 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      I already says that sort the strings in decreasing order according to length.

      • »
        »
        »
        »
        6 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        Yes, missed that. However, it is still wrong: abcbc, {bc, ab}. Removing bc yields a**bc, and ab is left, however searching in the reverse order would find both ab and bc.

        • »
          »
          »
          »
          »
          6 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Yes, You are right but what about this one

          • »
            »
            »
            »
            »
            »
            6 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

            I've already responed in that thread that my initial approach was wrong. The list needs to be topologically sorted before searching.

            • »
              »
              »
              »
              »
              »
              »
              6 лет назад, # ^ |
                Проголосовать: нравится 0 Проголосовать: не нравится

              What's wrong with my This approach

              • »
                »
                »
                »
                »
                »
                »
                »
                6 лет назад, # ^ |
                  Проголосовать: нравится 0 Проголосовать: не нравится

                Nothing's wrong, but how do you choose the ranges such that they do not interleave?

                • »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  »
                  6 лет назад, # ^ |
                    Проголосовать: нравится 0 Проголосовать: не нравится

                  connect all range of (i)th string of (i + 1)th string ranges according to condition that (two ranges connect if they do not overlap.

                  then range of (i + 1)th string to (i + 2)th string range and so on ...

                  and at last find a path if we can reach from 1st string to the last string..

                  if there is a path then answer is "YES" otherwise "NO"

  • »
    »
    6 лет назад, # ^ |
    Rev. 2   Проголосовать: нравится +3 Проголосовать: не нравится

    Replacing with asterisks instead of deleting does not fix the problem.

»
6 лет назад, # |
Rev. 6   Проголосовать: нравится +1 Проголосовать: не нравится
  1. Perform topological sorting of the list. We assume a directed edge between items (a, b) if there is a suffix of a which is a prefix of b. We do a regular toposort of this graph. Then, we reverse the order.
  2. Calculate hashes of strings in the list and store them. Also calculate hashes of prefixes of the master string.
  3. Search for each string using sliding window technique, from the start of the master string. Track characters of the master string which belong to the found items. When encountering such character, start over from the next one. If an item is not found, return false.
  4. All items are found, return true.

Steps 1-2 are essentially Rabin-Karp algorithm. Could be replaced with any string search algorithm of your choice.

  • »
    »
    6 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    Master string contains other characters as well.

    on the step 4, if you came to the end of the string, and the set is nonempty, you start from the next character. Why is it working?

    • »
      »
      »
      6 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      We assume that the first character doesn't belong to any string from the list, Therefore, we skip it.

      • »
        »
        »
        »
        6 лет назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        You are skipping first character this i understood.

        I am asking, are you reseting the set or not for next iteration?

        How will it work for master string "monkeyouxzmonkeyuo" and {"monkey", "you"}

        In this example skipping starting character only can't solve right?

        You have to skip 'x', 'z' also.

        • »
          »
          »
          »
          »
          6 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          You can skip several characters in a row. In you case it won't skip any, because monkey and you are found one after the other. But, for example, in monkeyxxxyou, we will skip three characters (xxx).

          • »
            »
            »
            »
            »
            »
            6 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

            No, 'y' is common.

            This is the thing, how is your approach skipping xxx in monkeyxxxyou?

            • »
              »
              »
              »
              »
              »
              »
              6 лет назад, # ^ |
              Rev. 4   Проголосовать: нравится 0 Проголосовать: не нравится

              Haha, yes, it seems that approach is wrong, it fails on the same example I've provided for starboy_jb. When one string has a prefix that is a suffix of another the order of which string to search for first matters. I'll update the comment.

»
6 лет назад, # |
Rev. 2   Проголосовать: нравится 0 Проголосовать: не нравится

Store the all the occurring range of a string.

And then find the non — interleaving range from all the range.

If it found then "YES" otherwise "NO"

for ex: master string = "monkeyoumonkeyuo"

for the string "monkey" = ( {0 , 5} , {8 , 13} )

for the string "you" = ( {5 , 7} )

then non-interleaving range (must choose one range from all strings) = ( {8 , 13} , {5 , 7} )

so the answer is "YES"