2017-03-09 84 views
1

什麼是對R.將文本轉換爲Pig Latin的好方法下面是我想出了將文本轉換爲豬拉丁語中的R

x = "pig" 
paste(toupper(substr(x,2,2)), substr(x,3,nchar(x)), tolower(substr(x,1,1)), "ay", sep = "") 
#[1] "Igpay" 

它適用於大部分的解決方案,但我還沒有想出瞭解如何以有效的方式將輸出的情況與輸入的情況進行匹配。具體而言,

  • 輸出的第一個字母應具有相同的情況下,作爲輸入的第一個字母,和
  • 隨後的字母應該有相同的情況下,作爲輸入

的後續字母對例如,

  1. "mac"將需要"acmay"
  2. "Mac"將需要"Acmay"
  3. ​​將需要"CcOymay"

我或許可以用一個循環做到這一點,但我想知道是否有更有效的方式來做到這一點。

+0

請參見[如何編寫在R中生成豬拉丁語的函數](http://stackoverflow.com/questions/40579426/how-to-write-function-that-generates-pig-latin-in-r) –

+0

@WiktorStribiżew,謝謝!我最大的問題是在開始和隨後的地方匹配案件。 –

+1

我還沒有研究過這個話題,但是從我所看到的話來看,在單詞start處有一些輔音簇存在問題。我懷疑完整的解決方案是可能的純正則表達式。看到[GitHub上的Pig Latin轉換PHP庫](https://github.com/simplonco/php-pig-latin)。 –

回答

3

該評論中的suggested answer未說明miXedCase翻譯。 (坦率地說,我不確定OP的意圖是否攜帶大寫字母的位置嚴格地說是「合適的豬拉丁」,但是如果你要做一個準(不那麼)的crypt分析在豬拉丁語中,正確大寫的字母可能會顯示出來。)

對高位/低位轉換進行硬編碼有點難以處理。我認爲最好是專門查看源字符串中的每個字母並將其轉換爲目標。這應該處理camelCase(這在語言中不一定有意義,但在某些情況下可能適用)。處理全部大寫單詞時需要特殊處理。

您將受益於將其分解爲功能組件。一個小遊戲後(而不是試圖太難效率),我建議這些功能:

whichUpperL <- function(strings) { 
    gr <- gregexpr("[A-Z]", strings) 
    mapply(function(g, len) { 
    if (any(g < 0)) return(rep(FALSE, len)) 
    if (length(g) == len) return(rep(TRUE, len)) 
    ret <- rep(FALSE, len) 
    ret[g] <- TRUE 
    return(ret) 
    }, gr, nchar(strings)) 
} 

toupper2 <- function(st, cond, default = NA) { 
    if (length(st) != length(cond)) stop("'st' and 'cond' not the same length") 
    mapply(function(s, isupper) { 
    lendiff <- max(0, length(s) - length(isupper)) 
    if (lendiff > 0) { 
     if (is.na(default)) default <- all(isupper) 
     isupper <- c(isupper, rep(default, lendiff)) 
    } 
    paste(ifelse(isupper, toupper(s), tolower(s)), collapse = "") 
    }, strsplit(st, ""), cond) 
} 

toPig <- function(strings) { 
    nchar3 <- (nchar(strings) > 2) 
    isupper <- whichUpperL(strings) 
    strings[nchar3] <- sapply(strings[nchar3], 
          function(s) paste(substr(s, 2, nchar(s)), substr(s, 1, 1), "ay", sep = "")) 
    toupper2(strings, isupper) 
} 

子funcs中的簡單的演示:

strings <- c("mac", "Mac", "McCoy", "MCCOY") 
str(whichUpperL(strings)) 
# List of 4 
# $ : logi [1:3] FALSE FALSE FALSE 
# $ : logi [1:3] TRUE FALSE FALSE 
# $ : logi [1:5] TRUE FALSE TRUE FALSE FALSE 
# $ : logi [1:5] TRUE TRUE TRUE TRUE TRUE 

toupper2("hello", list(c(TRUE, FALSE, TRUE, FALSE, TRUE))) 
# [1] "HeLlO" 

處理更長的字符串中toupper2的邏輯是很重要。沒有它,你可能(a)總是低於或大於"ay",或(b)回收邏輯,這會產生有趣的(和令人沮喪的)副作用。你不能硬編碼2的擴展名,因爲不是所有的豬拉丁字都用兩個字母來擴展一個單詞。我默認爲NA,以便它可以根據甚至是單個小寫字母的存在來確定;如果default=TRUE,那麼附加字母總是大寫(很少正確?);如果default=FALSE,那麼字母總是較低(如果整個單詞是較高的,則錯誤);如果default=NA這裏是正常的行爲,那麼如果所有其他字母都是較高的,那麼它將會更高。

給出的測試字符串:

toPig(strings) 
# [1] "acmay" "Acmay" "CcOymay" "CCOYMAY" 

這只是實現的豬拉丁語翻譯規則的基本情況。有other rules,你需要考慮,在這種情況下toPigsubstr邏輯將需要稍微修改。可能會使用正則表達式(只需查找主要元音或兩個主要非元音)。