2013-06-10 7 views
7

Chciałbym napisać funkcję, która sprawdza, czy słowo jest palindromu. powrót powinien mi powiedzieć jakjak sprawdzić, czy słowo jest palindromem?

palindrome "love" is not a palindrome  

funkcja powinna zawierać słowo (nie jako wektor) jako argumentu (I naprawdę nie rozumiem, co to znaczy)

Próbowałem

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

character==palinum 
} 

ale

Palindrome ("love") 

powraca

NA 

dzięki za pomoc!

+1

Um, konwertowanie 'pasta (revchar, zwinąć = "")' do numeryczna ... co zrobić oczekujesz czegoś innego niż 'NA'? –

+0

dzięki! ale teraz powrót mówi tylko "THRUE" lub "False", jak mogę sprawić, by mówiono "Hello is no palindrome"? – user2373707

+0

@ user2373707 użyj 'if-else' i' paste' – eddi

Odpowiedz

5

Bez użycia strsplit:

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

To podejście będzie dotyczyło tylko znaków ASCII: 'is.palendrome (" oço ")' – hadley

+0

facedictionary. Dzięki @BenBolker. – BenBarnes

+1

@Hadley, twój przykład (i przeciw-przykład 'is.palindrome (" oçro ")') działają zgodnie z oczekiwaniami na mojej instalacji. Nie wiem, dlaczego istnieje rozbieżność (jestem w locale Latin-1, sekwencja bitów ç jest symetryczna). Sprawdzę to później. – BenBarnes

3

to będzie działać:

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

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

Ponadto, sprawdź pakiet Kmisc dla wyników przypuszczalnie szybciej:

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

dziękuję! ale jak mogę sprawić, by powrócił (Otto) jak THRUE (otto)? – user2373707

1

Może być również wykonane przy użyciu substring() i rev() funkcje:

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

Oto C++ realizacja:

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; 
} 
') 

To nie działa z ciągów spoza ASCII albo, ale to około 10x szybciej niż czysty roztwór R:

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

Istnieje funkcja w stringi pakiet za to - stri_reverse

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

Teraz palindrom funkcja może takie proste:

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