Finding a substring inside a string with any order of substring characters in C / C ++

Suppose I have the string "abcdpqrs", now "dcb" can be considered a substring over the string, since the characters are together. Also, "pdq" is part of the above line. But "bcpq" is not. I hope you have what I want. Is there an effective way to do this. All I can think of is to use a hash for this. But it takes a lot of time even in the O (n) program, since in many cases a rollback is required. Any help would be appreciated.

+4
source share
5 answers

Here is a solution of size O (n * alphabet):

[a] = a [pos; pos + - 1]. O (1) , 1 (count [s [pos]] -, count [s [pos + length length]] ++, pos ++). , , pos, count count ( ).

O (n + ):

count diff = , , . , diff , count [c] - count [c] ++ ( , , count [c]). count , diff pos.

+3

, "axcdlef" "opde":

bool compare (string s1, string s2)
{
  // sort both here
  // return if they are equal when sorted;
}

4 ( , "opde" ):

"axcd" "Xcdl" "Cdle" "Dlef"

  bool exist = false;

  for (/*every split that has the same size as the search */)
      exist = exist || compare(currentsplit, search);
+1

(, boost Qt). . k s str. k str , - s.

( ):

#include <iostream>

/* pos position where to extract probable string from str
*  s string set with possible repetitions being searched in str
*  str original string
*/
bool find_in_string( int pos, std::string s, std::string str)
{
    std::string str_s = str.substr( pos, s.length());
    int s_pos = 0;

    while( !s.empty())
    {
        std::size_t found = str_s.find( s[0]);
        if ( found!=std::string::npos)
        {
            s.erase( 0, 1);
            str_s.erase( found, 1);
        } else return 0;
    }

    return 1;
}

bool find_in_string( std::string s, std::string str)
{
    bool found = false;
    int pos = 0;    
    while( !found && pos < str.length() - s.length() + 1)
    {
        found = find_in_string( pos++, s, str);
    }

    return found;
}

:

int main() {

    std::string s1 = "abcdpqrs";
    std::string s2 = "adcbpqrs";
    std::string searched = "dcb";
    std::string searched2 = "pdq";
    std::string searched3 = "bcpq";
    std::cout << find_in_string( searched, s1);
    std::cout << find_in_string( searched, s2);
    std::cout << find_in_string( searched2, s1);
    std::cout << find_in_string( searched3, s1);

    return 0;
}

: 1110

http://ideone.com/WrSMeV

0

, , ... , "a" - "z" - , 'a', .

bool compare(string s1, string s2)
{
   int v1[SIZE_OF_ALFABECT];
   int v2[SIZE_OF_ALFABECT];
   int count = 0;
   map<char, int> mymap;

  // here is just pseudocode
   foreach letter in s1:
      if map doesnt contain this letter already:
           mymap[letter] = count++;

 // repeat the same foreach in s2

 /* You can break and return false here if you try to add new char into map, 
  that means that the second string has a different character already... */

 // count will now have the number of distinct chars that you have in both strs

 // you will need to check only 'count' positions in the vectors

 for(int i = 0; i < count; i++)
    v1[i] = v2[i] = 0;

 //another pseudocode
   foreach letter in s1:
      v1[mymap[leter]]++;
   foreach letter in s1:
      v2[mymap[leter]]++;

  for(int i = 0; i < count; i++)
      if(v1[i] != v2[i])
          return false;

  return true;
}
0

O (m), O (m!) - m - :

-trie, . a Ukkonnen Trie ( , ), . , O (1) , n.

, n , m.

, , n , , trie , .

O (m).

I would suggest going with the accepted answer to the general case. However, here you have a suggestion that might perform (much) better for small substrings and large strings.

-1
source

Source: https://habr.com/ru/post/1545515/


All Articles