2011-01-03 3 views
5

포스트 스크립트/PDF 문자열 리터럴은 괄호로 묶여 있으며 괄호가 완전히 균형이 잡혀있는 경우 이스케이프 처리되지 않은 괄호 을 포함 할 수 있습니다.. 그래서 예를 들어문자열의 불균형 괄호를 찾는 알고리즘

(()) % valid string constant 
(() % invalid string constant, the inner (should be escaped 

나는 문자열에서 어떤 불균형 괄호가있는 경우 알고리즘이 말해 알고; 내가 찾고있는 알고리즘은 불균형 괄호의 최소한의 집합을 찾을 알고리즘입니다, 그래서 그 전 백 슬래시를 전체 유효한 문자열 리터럴로 만들 수 있습니다. 더 많은 예제 :

( ⟶ \(
() ⟶ () 
(() ⟶ \(() or (\() 
()) ⟶ ()\) or (\)) 
()( ⟶ ()\(
+0

코드 예제의 기본 언어는 무엇입니까? –

+0

입력 문자열의 크기는 얼마나됩니까? – marcog

+0

이 프로젝트는 현재 파이썬으로 작성되었습니다. 두 번째 선호도는 C 계열입니다. 다른 언어로 손을 쓸 수있는 일이 생기면 (의도적으로 쓰기 전용 언어가 아닌 한) 내가 처리 할 수 ​​있습니다. – zwol

답변

3

불균형 괄호를 감지하는 표준 스택 기반 알고리즘을 수정하면 효과가 있습니다. 다음은 몇 가지 의사 코드입니다.

void find_unbalaned_indices(string input) 
{ 
    // initialize 'stack' containing of ints representing index at 
    // which a lparen (was seen 

    stack<int index> = NIL   

    for (i=0 to input.size()) 
    { 
     // Lparen. push into the stack 
     if (input[i] == '(') 
     { 
      // saw (at index=i 
      stack.push(i); 
     } 
     else if (input[i] == ')') 
     { 
      out = stack.pop(); 
      if (out == NIL) 
      { 
       // stack was empty. Imbalanced RParen. 
       // index=i needs to be escaped 
       ... 
      } 
      // otherwise, this rparen has a balanced lparen. 
      // nothing to do. 
     } 
    } 

    // check if we have any imbalanced lparens 
    while (stack.size() != 0) 
    { 
     out = stack.pop(); 
     // out is imbalanced 
     // index = out.index needs to be escaped. 
    } 
} 

희망이 있습니다.

+0

그것은 욕심이 많으므로 항상 그렇게 잘 작동하지는 않습니다. – marcog

+3

이것이 실패 할 경우를 강조 할 수 있습니까? 내 생각은 O (N) (문자열의 길이)보다 빨리 수행 할 수 없다는 것이 었습니다. 나는 적어도 한 번 숯을 읽어야한다. –

+0

이것은 나에게 좋을 것 같습니다. 모든 것을 균형있게 유지하는 데 필요한 가장 가까운 괄호를 벗어나므로 좋은 선택입니다. – munificent

0
def escape(s): 
    return ''.join(r(')(', r('()', s))) 

def r(parens, chars): 
    return reversed(list(escape_oneway(parens, chars))) 

def escape_oneway(parens, chars): 
    """Given a sequence of characters (possibly already escaped), 
    escape those close-parens without a matching open-paren.""" 
    depth = 0 
    for x in chars: 
     if x == parens[0]: 
      depth += 1 
     if x == parens[1]: 
      if depth == 0: 
       yield '\\' + x 
       continue 
      else: 
       depth -= 1 
     yield x 
+0

이것이 효과가있는 것 같지만 이해할 수 없다고 생각합니다. 논리를 설명하고 백 슬래시의 수를 최소화한다는 논증을 제기 할 수 있습니까? – zwol

+0

escape_oneway()는 꽤 '직접'을 표현합니다. '('는 왼쪽에 일치하지 않으면 ')'를 이스케이프 처리해야합니다.대칭을 사용하면 오른쪽에 ''('일치하는 항목이없는 경우 이스케이프해야 함') '이 표시됩니다. 문자열을 뒤집고 '('및 ')'에 대한 검사를 바꾸면 첫 번째 경우로 줄입니다. 역 분개를 취소하려면 최종 반전이 있습니다. 나는 두 번째 패스가 이스케이프가 첫 번째 패스에서 내려진 결정에 영향을 미치지 않았을 때 확신했다. 그러나 나는 왜 비워 두었고 이제는 나가야한다. 어쩌면 내가 틀렸어. –

+0

이것은 올바르게 작동 할 수도 있지만 추론에 구멍이 있다고 생각합니다. "일치하는"(정확히 '일치 할 수있는'이 둘 이상있을 수 있습니다. ') 그래서 당신이 생각하는 것을 식별 할 필요가 있습니다. "일치"("당신이"일치 할 수있다 "는 것을 의미합니다, 초기 진술은 정확하지 않습니다 - 목격자는()). ')는 도망쳐 야하고 둘 중 하나만 잘 작동합니다. –

관련 문제