J'essaie d'inverser une chaîne sans utiliser d'espace supplémentaire dans R. Voici le code pour la même chose. Ma question est de savoir comment faire pour que la fonction ReverseString change l'entrée sans utiliser d'espace supplémentaire. J'ai même essayé d'utiliser sans aucune chance. ReverseString <- function(TestString){
TestString <- unlist(strsplit(TestString, ""))
Left <- 1
Right <- length(TestString)
while (Left < Right){
Temp <- TestString[Left]
TestString[Left] <- TestString[Right]
TestString[Right] <- Temp
Left <- Left + 1
Right <- Right - 1
}
return(paste(TestString, collapse = ""))
}
## Input
a = "StackOverFlow"
## OutPut
ReverseString(a)
"wolFrevOkcatS"
##
a
"StackOverFlow"
4 Réponses :
Cela peut être fait facilement avec stringi
library(stringi) a <- "StackOverFlow" stri_reverse(a) #[1] "wolFrevOkcatS"
Je sais que les fonctions intégrées peuvent être utilisées. Mais je me prépare à des interviews dans lesquelles on me demandera évidemment d'écrire le code à partir de zéro.
Il est toujours préférable de tirer parti de la vectorisation en R (au lieu des boucles for ou while). Donc, en base-R, sans aucun paquet, ce serait quelque chose comme:
ReverseString <- function(x) {
#splitstring splits every character, and rev reverses the order
out <- rev(strsplit(x, split = '')[[1]])
#paste to paste them together
paste(out, collapse = '')
}
a <- "StackOverFlow"
ReverseString(a)
#[1] "wolFrevOkcatS"
J'essaie de créer ma propre fonction sans utiliser de fonctions intégrées.
Il n'y a pas de fonctions intégrées ici (je traduis les fonctions intégrées en fonctions externes, car tout est intégré autrement). Tous font partie de base-R. Je comprends que dans certaines interviews, ils voudront peut-être que vous n'utilisiez aucun package externe, mais vous forcer à utiliser une boucle for ou while n'aurait pas de sens à mon avis.
vous avez raison. Dans l'une de mes entrevues, j'ai utilisé la commande de table pour obtenir la fréquence des mots, mais ils m'ont demandé si je pouvais écrire le code en utilisant ses propres fonctions et boucles.
Je pense que le but de ce genre de questions d'entrevue est de voir comment vous abordez les problèmes de calcul. N'importe qui peut appeler la fonction rev pour inverser l'ordre d'un vecteur. Ils veulent voir comment vous résolvez le problème avec les outils les plus simples possibles, c'est-à-dire des boucles et des index. Pourtant, cela ressemble plus à une question de laboratoire CS qu'une véritable question d'entrevue.
@gersht Je comprends que ce n'est pas une bonne idée. J'aurais dû être plus précis dans ma question. Je pratique ces questions pour mes prochaines interviews.
Selon votre commentaire, vous souhaitez inverser la chaîne sans appeler aucune fonction qui effectue l'inversion, c'est-à-dire pas de rev et co. Les deux solutions ci-dessous font cela.
Je pense que vous essayez également de modifier un a global à partir de la fonction, c'est pourquoi vous avez essayé . Je ne sais pas pourquoi cela n'a pas fonctionné pour vous, mais vous l'avez peut-être mal utilisé.
Vous devez savoir qu'utiliser seul ne signifie pas que vous utilisez moins d'espace. Pour vraiment économiser de l'espace, vous devrez appeler ou modifier le que vous auriez à faire pour accéder aux éléments de a global à chaque étape de votre fonction où vous appelez ou modifiez TestString . Cela impliquerait une combinaison de assign , do.call , eval et parse - sans parler de tous les coller a par position entière. Votre fonction finirait par être encombrante, presque illisible et très probablement moins efficace en raison des nombreux appels de fonction, bien qu'elle ait économisé une quantité négligeable d'espace en ne stockant pas une copie de a . Si vous êtes résolu à créer une telle abomination, jetez un œil aux fonctions que je viens d'énumérer et découvrez comment les utiliser.
Votre énergie serait mieux dépensée en améliorant votre inversion de chaîne fonctionner d’autres manières. Par exemple, vous pouvez le raccourcir un peu en utilisant une séquence numérique telle que 13: 1 dans sapply:
reverse_string2 <- function(string){
vec <- str_split(string, "")[[1]]
i_vec <- c(1, length(vec))
while(i_vec[1] < i_vec[2]) {
vec[i_vec] <- vec[c(i_vec[2], i_vec[1])]
i_vec <- i_vec + c(1, -1)
}
paste(vec, collapse = "")
}
reverse_string2("StackOverFlow")
#### OUTPUT ####
[1] "wolFrevOkcatS"
Si vos enquêteurs ont également un problème avec les séquences inversées, voici une autre option plus proche de votre code d'origine, juste un peu plus propre. J'ai également fait de mon mieux pour éliminer d'autres zones où un "espace supplémentaire" était utilisé (index stockés dans un seul vecteur, plus de Temp):
reverse_string <- function(string) {
vec <- str_split(string, "")[[1]]
paste(sapply(length(vec):1, function(i) vec[i]), collapse = "")
}
reverse_string("StackOverFlow")
#### OUTPUT ####
[1] "wolFrevOkcatS"
p>
Je ne suis pas sûr d'avoir compris exactement le problème, mais je pense que vous cherchez un moyen d'inverser l'objet string et de l'attribuer automatiquement à l'objet d'origine sans avoir à faire un (en supposant que c'est la raison pour laquelle vous avez essayé d'utiliser ). Ma solution consiste à utiliser deparse (substitute ()) pour lire le nom de la variable d'origine dans la fonction et assign (en utilisant envir = .GlobalEnv ) pour affecter votre résultat sur la variable d'origine. ReverseString <- function(TestString){
nm <- deparse(substitute(TestString))
TestString <- unlist(strsplit(TestString, ""))
Left <- 1
Right <- length(TestString)
while (Left < Right){
Temp <- TestString[Left]
TestString[Left] <- TestString[Right]
TestString[Right] <- Temp
Left <- Left + 1
Right <- Right - 1
}
assign(nm, paste(TestString, collapse = ""), envir = .GlobalEnv)
}
## Input
a = "StackOverFlow"
ReverseString(a)
a
#[1] "wolFrevOkcatS"
Je pense que c'est plus proche de ce que recherche l'OP quand il dit vouloir éviter «d'utiliser de l'espace supplémentaire». Le seul problème est qu'il utilise la même quantité d'espace car une copie de a est toujours faite, c'est juste que l'affectation se produit à l'intérieur de la fonction au lieu d'affecter la sortie de la fonction à a code >. Cependant, il s'agit plus d'une critique de la prémisse de la question que de votre solution.
Que voulez-vous dire exactement par "sans utiliser d'espace supplémentaire dans R"? Lancer votre code puis
ls ()me donne"a" "Reverse String". Il n'y a donc aucun objet supplémentaire qui a été créé.Construire votre propre fonction sans utiliser les fonctions intégrées est à mon avis trop large car on pourrait aussi argumenter que
tandis queetpoursont des fonctions intégrées.strsplit,unlistsont également des fonctions intégrées.@NelsonGon Je pense que l'OP signifie que la révision doit être effectuée sans utiliser de fonction intégrée. Quoi qu'il en soit, cela devrait certainement être clarifié dans la question.
@gersht Vous avez raison. Je voulais dire que l'inversion devrait être effectuée sans utiliser de fonction intégrée.
@JasonMathews J'ai trouvé quelques réponses qui pourraient vous être utiles. On renonce aux fonctions d'inversion, mais il utilise une séquence inverse, par ex.
13: 1. Si ce n'est pas autorisé, j'ai également adapté votre code pour supprimer autant que possible l'utilisation "d'espace supplémentaire", pas deTemp, etc. J'explique aussi pourquoi je pense que la modification des variables globales n'est probablement pas tout à fait une idée aussi géniale que vous pourriez le penser.