와일드 카드 문자열이 세트의 다른 와일드 카드 문자열과 완전히 일치하는지 판별


9

잠시 동안 나를 괴롭힌 문제가 있습니다. 문자열 이 1과 0 의 시퀀스이고 와일드 카드 문자열 이 1, 0 및? s 의 시퀀스 라고 가정하겠습니다 . 모든 문자열과 와일드 카드 문자열의 길이는 같습니다. 이들은 표준 UNIX 와일드 카드입니다. 10 ?? 1은 10011, 10111 등과 일치합니다. 해당 위치에서 1 또는 0과 일치합니다. 경우 및 와일드 카드 문자열, 우리는 쓰기 w V \ 당량 일치 모든 문자열 경우 V가 도 일치한다 w를 .vwvwvw

문제 : 와일드 카드 문자열 세트 S 와 쿼리 v (와일드 카드 문자열)가 주어지면 v \ leq w ? 와 같은 w \ in S가 있습니까? 그렇지 않은 경우 vS에 효율적으로 추가 할 수 있습니까?wSvwvS

다음은 명백한 O(kmn) 솔루션입니다 (여기서 k 는 문자열의 크기, m 은 RAM의 단어 크기 (일반적으로 32 또는 64)) : 목록의 각 요소를 살펴보고 테스트하십시오. 조건 (비트 트위들 링을 사용하여 2 또는 3 작업에서 수행 할 수 있음). 또한 스캔하는 동안 vw 가 모든 항목 w 를 보유 하는지 테스트하십시오 . 경우 v 우리의 테스트에 실패하고 추가 v 세트에, 그리고 제거 w 우리가 표시들 '.

그러나 그것은 충분히 빠르지 않습니다. O(logn) 솔루션이 있거나 완벽한 세계에서 기수 트리 ( O(k) ) 와 유사한 복잡성 이 있다면 정말 멋질 것입니다 . 쿼리가 대략 정확 하다는 것도 괜찮습니다 . 즉, vw 인 경우 yes 또는 no를 반환합니다. 그러나 조건이 확실하지 않으면 no를 반환하십시오.

이것이 최악의 경우에 도움이되지는 않지만 S의 모든 요소 S가 와일드 카드 문자열로 묶여 있다고 가정 할 수 있습니다 . 즉, 모든 w \ in S 에 대해 v \ geq w 와 같은 v 가 있습니다 .vwSvw

내가 시도한 아이디어

  • 와일드 카드 문자열은 결합-실 밀화를 형성합니다. 와일드 카드 문자열을 포함하는 n-ary 트리를 가질 수 있습니다. 나뭇잎은 와일드 카드 문자열이되고 가지는 모든 어린이의 조인을 나타냅니다. 쿼리와 조인을 비교할 수없는 경우 해당 지점의 모든 자식과 비교하려고 시간을 낭비하지 않아도됩니다. 또한 업데이트를 수행하고 업데이트가 조인보다 큰 경우 전체 분기를 간단히 삭제할 수 있습니다. 불행히도, 이것은 최악의 경우 여전히 이며, 요소를 추가하기 위해 트리를 스캔 할 때 항상 "최상의"조인을 찾지는 않습니다.O(n)
  • 의 기수 트리를 형성 할 수 있습니다. 우리는 가 와일드 카드 문자열에 의해 묶여 있음을 알고 있습니다 . 그것이? 0? 0이라고 가정하십시오. 그런 다음 trie의 모든 분기는 문자열의 첫 번째 비트와 세 번째 비트에만 있어야합니다. 쿼리에서 분기하는 현재 비트가 1이면? 그리고 1 개의 가지; 0이면?를 확인합니다. 그리고 0 가지; 그것이?라면, 우리는? 분기. 우리는 잠재적으로 여러 개의 브랜치를 가져야하기 때문에 그리 좋아 보이지 않습니다 (같은 이유로 트라이를 업데이트하기는 어렵습니다). 매칭은 매우 빠른 작업이므로 트리에서 많은 순회를 수행하는 순진한 전략과 비교할 때 아프다 (포인터를 따르는 것이 일부 OR 및 AND를 수행하는 것보다 훨씬 비쌉니다).SS

관련된 일

  • 네트워킹 커뮤니티에서이 문제는 "패킷 분류"로 나타납니다. 여기에는 알려진 알고리즘 및 데이터 구조에 대한 훌륭한 조사가 있습니다 . 불행하게도, 와일드 카드 문자열은 접두사 만 일치한다고 가정하고 쿼리는 이러한 문자열의 튜플입니다. 물론 일반적인 와일드 카드 문자열을 다음 기준에 맞게 변환 할 수 있습니다. 1? 00? 1 ?? (1, β, 0, 0, β, 1, β, β)이다. 그러나 이것은 효율적이지 않습니다. 다른 가정은 이러한 튜플이 "색상"과 연관되어 있고 쿼리는 색상이 일치하는 것만이 아니라 색상을 반환해야한다는 것입니다. 이것은 튜플을 주문해야하기 때문에 (또는 (0,?) 및 (?, 1) 중 어느 것이 (0, 1)과 일치하는지 모호하기 때문에) 문제를 훨씬 더 어렵게 만듭니다.

  • 알고리즘 커뮤니티에서 "무관심"과 일치하는 하위 문자열을 찾는 것과 관련된 많은 결과를 발견했습니다. 이것은 상당히 어려운 문제이며 실제로 어떤 기법도 사용할 수 없습니다.

결론적으로

도움을 주셔서 감사합니다!


1
줄은 얼마나 클 수 있습니까? 그리고 왜 복잡성에서 그들의 길이를 설명하지 않습니까? 분명히 문자열은 이어야합니다. 그렇지 않으면 작업 할 고유 한 문자열 이 없습니다 . 또한 길이의 문자열 을 허용 하면 최악의 경우 데이터 구조의 모든 문자열을 봐야합니다 ... 문자열 길이에 경계가 있습니까? 폴리 로그? ? Ω(logn)nO(n)o(n)
Artem Kaznatcheev

확실하지 않으면 죄송합니다. 문자열의 크기 는 입니다. 모든 의도와 목적을 위해 32 자 길이로 생각할 수 있습니다. "문자열"은 문제의 프레이밍을위한 편리한 추상화 일뿐입니다. 실제로는 (정수, 비트 마스크) 튜플로 표시되므로 몇 가지 기계 작업만으로 조인 및 를 계산할 수 있습니다 . (물론 정수 및 비트 마스크 필드의 수를 늘림으로써 문제는 더 큰 상수 크기 문자열로 자연스럽게 확장 될 수 있습니다). O(1)vw
Christopher Monsanto

위의 의견은 아마도 복잡성 인수에 도움이되지 않을 것입니다 : (. 실제로 문자열의 크기를 다양하게 허용하는 경우 문자열의 크기와 집합의 크기 사이에는 아무런 관계가 없습니다. 것에 대해 사실 어쨌든 내가 훨씬 더 평균의 경우 관심 (또는 근사치) 오전, 불행한 최악의 경우지만.O(n)
크리스토퍼 몬산토

답변:


3

유한 상태 오토 마톤을 사용하는 것은 어떻습니까? 언어 는 유한하므로 규칙적입니다. 아래의 변환 후에도 여전히 규칙적입니다. 따라서 정규식을 결정적 유한 상태 오토 마톤으로 변환하는 일반적인 단계를 수행 한 후 시간 에 원하는 것을 인식 할 수 있습니다 . 아래 제안 된 내용에 버그가있는 경우이 아이디어가 여전히 작동하기를 바랍니다.SO(k)

주름은 와일드 카드 연산자를 처리하는 방법입니다. 와일드 카드 문자열의 와일드 카드는 테스트 문자열의 0 또는 1과 일치합니다. 그러나 와일드 카드 문자열을 인식하려고하므로 와일드 카드 문자열의 와일드 카드는 0, 1 또는? 다른 와일드 카드 문자열에서. 이 세트는 여전히 규칙적이므로 모든? 수직 막대가 일반적인 대체 연산자 인 정규식 (0 | 1 |?) 따라서 전체 집합 가 {10 ?? 1, 0? 1? 0}이면 정규 표현식은 (10 (0 | 1 |?) (0 | 1 |?) 1 | 0 (0 | 1 | ?) 1 (0 | 1 |?) 0)S

머신에 문자열을 추가하는 경우, 유한 상태 오토 마톤을 점차적으로 변경하는 작업이 있습니다. Daciuk 등 의이 논문 을 참조하십시오 : "최소 비 환식 유한 상태 오토마타의 증분 구성".

도움이 되나요?


나는 automata를 고려했습니다. 그렇습니다. 그러나 나는 오토마타를 점진적으로 구성하는 그런 작업을 찾지 못했습니다. 포인터 ShyPerson에게 감사드립니다.
Christopher Monsanto

나는 Daciuk, et al 논문을 인용했다. 왜냐하면 그것이 달성하려는 것과 가장 비슷해 보였기 때문이다. 그러나 Carrasco와 Forcada의 논문 "최소 유한 유한 상태 자동 증분의 증분 구성 및 유지 관리"에서 finitepress state automata에 대한 문제가 최근에 더 많이 해결되었다고 언급 할 가치가 있다고 생각합니다. mitpressjournals.org/doi/abs/10.1162/ …
ShyPerson

좋아, 나는이 주제에서 더 많은 것을 얻을 것이라고 생각하지 않으므로 귀하의 답변을 받아들입니다. 감사!
Christopher Monsanto
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.