2016-08-22 2 views
-1

HackerRank의 pretty simple problem에서 며칠 동안 일해 왔지만 시간 초과 문제가있어 더 이상 코드를 최적화 할 수 없습니다.R 코드가있는 HackerRank의 The Grid Search

문제는 다음과 같습니다. 숫자의 2D 배열 (R * C 치수)이 주어지면 주어진 2D 패턴 (차원 * * c)의 발생을 찾으십시오. 여기

당신은 변수의 재현 예를 들면 다음과 같습니다

pattern <- c("11111", "11111", "11110") 
text <- c("111111111111111", 
"111111111111111", 
"111111011111111", 
"111111111111111", 
"111111111111111") 
R <- 5 
C <- 15 
r <- 3 
c <- 5 

그것은 정규식 문제의 일종이지만, 2D, 그리고 이것이 내가 즉시 사용 가능한 기능으로 어디서나 찾을 수있는 일입니다 in R. 내가 대처할 수 있었던 몇 가지 모서리 사례가 있습니다. 위의 버전은 일반적인 경우 '정규식'이 비참하게 패턴을 찾지 못하는 경우 중 하나입니다. .

아래 코드는 15 개 중 13 개가 완벽하게 작동하지만 일부 테스트 (예 : R * C = 500 * 500 및 r * c = 236)와 비교하여 시간 초과로 인해 실패합니다. * 208.

RW <- c() 
    pattern2 <- paste0(pattern, collapse = "") 
    RW <- c(rep(NA,(C-c+1)*(R-r+1))) 
    for (v in 1:(C-c+1)) 
    { 
     for (y in 1:(R-r+1)) 
     { 
     RW[(C-c+1)*(y-1)+v] <- paste0(substr(text[y:(y+r-1)],v,c+v-1),collapse="") 
     } 
    } 
    per <- ifelse(pattern %in% RW, result <- "YES",result <- "NO") 
    cat(result, "\n") 

각 시험 5 건까지가 있습니다,이 내 코드가 실패하는 이유입니다하십시오 : 그것은 5 개 부분으로 테스트를 깨는 일 수 있지만,이 경우는 시간 임계 값 전달 큰 R C 및 r 치수와 함께 결합됩니다.

아무도 코드 성능을 향상시키는 방법에 대한 아이디어가 있습니까?

+0

: 이것은 당신이 (당신이 준 테스트 케이스를 해결, 나는 믿는다) 같은 것을 할 수 있다는 것을 의미합니다. – nrussell

+0

SO가 들여 쓰기 공간이 4 개 이상인 코드를 좋아하지 않으므로 들여 쓰기를 제거했습니다. 자, 내 코드의 성능에 대해 알고 싶습니까? :) – MaZe

+1

한 번에 한 요소 씩 결과를 늘리는 것이 R :'RW [length (RW) +1] <- [...]'의 고전적인 "성능 킬러"입니다. 'RW'를 올바른 길이로 초기화해야합니다. 성능과는 무관하게, 변수'ifelse '의 이름을 짓는 것은 좋은 방법이 아닙니다. – nrussell

답변

1

접근 방식을 유지하려는 경우 substr이 아마도 매우 빠르지 않기 때문에 첫 번째 제안은 문자열을 숫자 행렬로 변환하는 것입니다.

Knuth-Morris-Pratt Algorithm과 같은 두 개 이상의 장소에서 위치를 이동시키는보다 정교한 검색 알고리즘을 더 사용할 수 있습니다.

그러나, for 루프는 항상 R에서 매우 느릴 것이므로이 상황에서 가장 좋은 방법은 실제로 정규 표현식이라고 생각합니다. 큰 그리드의 행을 하나의 긴 문자열로 연결하면 패턴의 행 사이의 문자 수가 고정됩니다. 당신의`for` 루프하는 하나 개의 개선 들여 쓰기

grepl(
    paste0(pattern[1], ".{", C - c, ",}", 
      pattern[2], ".{", C - c, "}", 
      pattern[3]), 
    paste0(text, collapse = "") 
    ) 

https://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm

+0

이것은 꽤 훌륭하고 실제로 구현할 수 없었기 때문에 실제로 정규 표현식의 힘을 사용합니다. 나는 그것에 대해 생각해 봤지만 계속 나아가고 싶었 기 때문에 내 생각을 사용하려고 시도조차하지 않았습니다. 그럼에도 불구하고, 붙여 넣기 할 패턴 요소의 색인을 생성하는 방법을 찾아야합니다 ...하지만 감사합니다. 알려 주시면 알려 드리겠습니다. – MaZe

+0

'grepl'은 제 경우에 사용하지 못하게하는 중요한 제한이 있다는 것을 발견했습니다.'C-c' 값이 255를 초과하면 함수가 오류를 던집니다. 이것은 R 도움말에서 찾은 것입니다. _ 정규 표현식을 길게는 받아들이지 않을 수도 있습니다. POSIX 표준은 최대 256 바이트 만 필요합니다 ._ 다른 방법을 찾아야하지만 다시 붙어 있습니다 : KMP 알고리즘은 (처음 보면) 236 * 208 패턴을 가진 500 * 500 텍스트에서 더 느린 것처럼 보입니다 ... – MaZe

+0

이 경우에는 각 그리드 열의 각 패턴 행을 검색 할 수 있습니다 (예 : grep). 이 방법으로 당신은 (희망적으로 적은 수의) "후보 행"을 얻을 수 있습니다. – AEF