2013-06-10 22 views
7

Ich möchte eine Funktion schreiben, die überprüft, ob ein Wort ein Palindrom ist. die Rückkehr sollte mir sagen, wieWie überprüft man, ob ein Wort ein Palindrom ist?

palindrome "love" is not a palindrome  

die Funktion das Wort (nicht als Vektor) als Argument enthalten soll (Ich verstehe nicht wirklich, was es bedeutet)

Ich versuchte

Palindrome <- function(character){ 
charsplit <- strsplit(as.character(character), "") 
revchar <- rev(unlist(charsplit)) 
palinum <- as.numeric(paste(revchar, collapse="")) 

character==palinum 
} 

aber

Palindrome ("love") 

kehrt

NA 

danke für jede Hilfe!

+1

Um, Sie konvertieren 'Paste (revchar, Kollaps = "")' auf numerische ... was tun Sie erwarten andere als 'NA'? –

+0

danke! aber die Rückkehr sagt jetzt nur "THRUE" oder "False", wie kann ich es machen zu sagen "Hallo ist kein Palindrom"? – user2373707

+0

@ user2373707 verwenden 'if-else' und' einfügen' – eddi

Antwort

5

Ohne strsplit mit:

is.palindrome <- function(word) { 
    rawWord <- charToRaw(tolower(word)) ## converts to lower case 
    sprintf("%s is %sa palindrome", word, 
     c("not ", "")[identical(rawWord, rev(rawWord)) + 1]) 
} 

> is.palindrome("otto") 
[1] "otto is a palindrome" 
> is.palindrome("love") 
[1] "love is not a palindrome" 
> is.palindrome("Otto") 
[1] "Otto is a palindrome" 
+4

Dieser Ansatz wird nur mit ASCII-Zeichen verwendet: 'is.palendrome (" oço ")' – hadley

+0

facedictionary. Danke @BenBolker. – BenBarnes

+1

@hadley, Ihr Beispiel (und das Gegenbeispiel 'is.palindrome (" oçro ")') funktionieren wie erwartet in meinem Setup. Nicht sicher, warum es eine Diskrepanz gibt (ich bin in einem Latin-1-Locale; die Bit-Sequenz von ç ist symmetrisch). Ich werde später mehr nachsehen. – BenBarnes

3

arbeiten Dies würde:

a = "blahalb" 
identical(strsplit(a, "")[[1]], rev(strsplit(a, "")[[1]])) 
#[1] TRUE 

a = "love" 
identical(strsplit(a, "")[[1]], rev(strsplit(a, "")[[1]])) 
#[1] FALSE 

Auch Besuche die Kmisc Paket für vermutlich schnellere Ergebnisse:

library(Kmisc) 

a = c("blahalb", "love") 
str_rev(a) == a 
#[1] TRUE FALSE 
5
is.palindrome <- function (word) { 
    identical(word, paste(rev(strsplit(word, "")[[1]]), collapse="")) 
} 

is.palindrome("kayak") 
[1] TRUE 

is.palindrome("love") 
[1] FALSE 
2
is_palindrome <- function(word){ 
    charsplit <- strsplit(word, "")[[1]] 
    revchar <- rev(charsplit) 

    all(charsplit==revchar) 
} 

is_palindrome("love") 
is_palindrome("otto") 
+0

danke! aber wie kann ich es schaffen, (Otto) als THRUE wie (Otto) zurückzukehren? – user2373707

1

Kann auch substring() und rev() Funktionen erfolgen:

is_palindrome <- function(x){ 

a <- substring(x,seq(1,nchar(x),1) , seq(1,nchar(x),1)) 
paste(rev(a),sep="",collapse="") == paste(a,sep="",collapse="") 

} 
1

Hier ist eine C++ Implementierung:

sourceCpp(' 
bool isPalindrome(String x) { 
    std::string y(x); 
    int n = y.size(); 

    for(int i = 0; i < n/2; ++i) { 
    if (y[i] != y[n - i - 1]) return false; 
    } 

    return true; 
} 
') 

Es funktioniert nicht mit Nicht-ASCII-Zeichenketten entweder, aber es ist etwa 10x schneller als die reine R-Lösung:

library(microbenchmark) 
options(digits = 3) 

is.palindrome <- function (word) { 
    identical(word, paste(rev(strsplit(word, "")[[1]]), collapse="")) 
} 

x <- paste(letters, rev(letters), collapse = "") 
y <- paste("a", x) 

microbenchmark(
    is.palindrome(x), 
    isPalindrome(x), 
    is.palindrome(y), 
    isPalindrome(y) 
) 
# Unit: microseconds 
#    expr min lq median uq max neval 
# is.palindrome(x) 24.62 25.99 27.14 28.29 36.38 100 
# isPalindrome(x) 2.38 2.68 2.82 3.58 4.03 100 
# is.palindrome(y) 24.68 26.44 27.78 28.46 80.94 100 
# isPalindrome(y) 2.33 2.67 3.41 3.64 33.60 100 
1

Es gibt eine Funktion in stringi Paket für das - stri_reverse

require(stringi) 
stri_reverse("eye") 
## [1] "eye" 
stri_reverse("1234") 
## [1] "4321" 

Jetzt Palindrom Funktion könnte so einfach wie das:

palindrome <- function(x) stri_reverse(x)==x 
palindrome(c("love","1234321","eye","oço","ąłą")) 
## [1] FALSE TRUE TRUE TRUE TRUE 
Verwandte Themen