Quel est le moyen le plus efficace d'inverser une chaîne en Java? Devrais-je utiliser une sorte d'opérateur xor? Le moyen le plus simple serait de mettre tous les caractères dans une pile et de les remettre dans une chaîne, mais je doute que ce soit une façon très efficace de le faire.
Et s'il vous plaît, ne me dites pas d'utiliser certaines fonctions intégrées en Java. Je suis intéressé à apprendre à le faire pour ne pas utiliser une fonction efficace sans savoir pourquoi elle est efficace ou comment elle est construite.
Vous dites que vous voulez connaître le moyen le plus efficace et que vous ne voulez pas connaître une manière standard de le faire. Alors je vous dis: RTSL (lisez la source, luke):
Consultez le code source pour AbstractStringBuilder # reverse , appelé par StringBuilder # reverse. Je parie que cela fait des choses que vous n'auriez pas considérées comme une opération inverse robuste.
Ce qui suit ne traite pas des paires de substitution UTF-16.
public static String reverse(String orig)
{
char[] s = orig.toCharArray();
int n = s.length;
int halfLength = n / 2;
for (int i=0; i<halfLength; i++)
{
char temp = s[i];
s[i] = s[n-1-i];
s[n-1-i] = temp;
}
return new String(s);
}
Vous avez dit que vous ne voulez pas le faire facilement, mais pour ceux qui recherchent Google, vous devez utiliser StringBuilder.reverse :
String reversed = new StringBuilder(s).reverse().toString();
Si vous avez besoin de l'implémenter vous-même, parcourez les caractères dans l'ordre inverse et ajoutez-les à un StringBuilder. Vous devez faire attention s'il y a (ou peut être) des paires de substitution, car elles ne devraient pas être inversées. La méthode présentée ci-dessus le fait automatiquement pour vous. C'est pourquoi vous devriez l'utiliser si possible.
Un vieux post et une question, mais ne trouvaient toujours pas de réponses concernant la récursion. Méthode récursive inverse la chaîne donnée s, sans relayer les fonctions jdk intégrées
public static String reverse(String s) {
if (s.length() <= 1) {
return s;
}
return reverse(s.substring(1)) + s.charAt(0);
}
`
Le moyen le plus rapide serait d’utiliser la méthode reverse()
sur les classes StringBuilder
ou StringBuffer
:)
Si vous voulez l'implémenter vous-même, vous pouvez obtenir le tableau de caractères, allouer un second tableau de caractères et déplacer les caractères. Dans le pseudo-code, cela ressemble à ceci:
String reverse(String str) {
char[] c = str.getCharArray
char[] r = new char[c.length];
int end = c.length - 1
for (int n = 0; n <= end; n++) {
r[n] = c[end - n];
}
return new String(r);
}
Vous pouvez également exécuter la moitié de la longueur du tableau et échanger les caractères, les vérifications impliquées ralentiront probablement les choses.
Je ne suis pas vraiment sûr de ce que vous voulez dire quand vous dites que vous avez besoin d'un algorithme efficace.
Les manières d'inverser une chaîne que je peux penser sont (elles sont toutes déjà mentionnées dans d'autres réponses):
Utilisez une pile (votre idée).
Créez une nouvelle chaîne inversée en ajoutant des caractères un par un dans l'ordre inverse de la chaîne d'origine à une chaîne vide/StringBuilder/char [].
Échangez tous les caractères dans la première moitié de la chaîne avec la position correspondante dans la dernière moitié (c.-à-d. Que le ieme caractère est échangé avec le (longueur-i-1) ème caractère).
Le fait est que tous ont le même complexité d'exécution: O (N). Ainsi, on ne peut pas vraiment affirmer que l’un est significativement meilleur que les autres pour les très grandes valeurs de N (c’est-à-dire les très grandes chaînes).
La troisième méthode a une chose pour elle, les deux autres nécessitent O(N) d'espace supplémentaire (pour la pile ou la nouvelle chaîne), alors qu'elle peut effectuer des permutations sur place. Mais les chaînes de caractères étant immuables en Java, vous devez de toute façon effectuer des permutations sur un StringBuilder/char [] nouvellement créé et ainsi avoir besoin de plus d'espace O(N).
public class ReverseInPlace {
static char[] str=null;
public static void main(String s[]) {
if(s.length==0)
System.exit(-1);
str=s[0].toCharArray();
int begin=0;
int end=str.length-1;
System.out.print("Original string=");
for(int i=0; i<str.length; i++){
System.out.print(str[i]);
}
while(begin<end){
str[begin]= (char) (str[begin]^str[end]);
str[end]= (char) (str[begin]^str[end]);
str[begin]= (char) (str[end]^str[begin]);
begin++;
end--;
}
System.out.print("\n" + "Reversed string=");
for(int i=0; i<str.length; i++){
System.out.print(str[i]);
}
}
}
private static String reverse(String str) {
int i = 0;
int j = str.length()-1;
char []c = str.toCharArray();
while(i <= j){
char t = str.charAt(i);
c[i] = str.charAt(j);
c[j]=t;
i++;
j--;
}
return new String(c);
}
Je pense que si vous n’avez VRAIMENT pas de problème de performances, vous devriez simplement choisir la solution la plus lisible, à savoir:
StringUtils.reverse("Hello World");
char* rev(char* str)
{
int end= strlen(str)-1;
int start = 0;
while( start<end )
{
str[start] ^= str[end];
str[end] ^= str[start];
str[start]^= str[end];
++start;
--end;
}
return str;
}
=========================
Première opération:
x1 = x1 XOR x2
x1: 1 0 0
x2: 1 1 1
New x1: 0 1 1
Deuxième opération
x2 = x2 XOR x1
x1: 0 1 1
x2: 1 1 1
New x2: 1 0 0
//Notice that X2 has become X1 now
Troisième opération:
x1 = x1 XOR x2
x1: 0 1 1
x2: 1 0 0
New x1: 1 1 1
//Notice that X1 became X2
Je le ferais simplement de cette façon sans utiliser une seule fonction util. Juste la classe String est suffisante.
public class MyStringUtil {
public static void main(String[] args) {
String reversedString = reverse("StringToReverse");
System.out.println("Reversed String : " + reversedString);
}
/**
* Reverses the given string and returns reversed string
*
* @param s Input String
* @returns reversed string
*/
private static String reverse(String s) {
char[] charArray = s.toCharArray(); // Returns the String's internal character array copy
int j = charArray.length - 1;
for (int i = 0; charArray.length > 0 && i < j; i++, j--) {
char ch = charArray[i];
charArray[i] = charArray[j];
charArray[j] = ch;
}
return charArray.toString();
}
}
Vérifie ça. À votre santé!!
Si vous ne souhaitez utiliser aucune fonction intégrée, vous devez revenir en arrière avec la chaîne en ses composants: un tableau de caractères.
Maintenant, la question est de savoir quel est le moyen le plus efficace d’inverser un tableau. Dans la pratique, la réponse à cette question dépend également de l'utilisation de la mémoire (pour les très grandes chaînes), mais en théorie, l'efficacité est mesurée dans les cas d'accès aux tableaux.
Le moyen le plus simple consiste à créer un nouveau tableau et à le renseigner avec les valeurs que vous rencontrerez lors d'une itération inverse sur le tableau d'origine et de renvoyer le nouveau tableau. (Bien qu'avec une variable temporaire, vous pouvez également le faire sans un tableau supplémentaire, comme dans la réponse de Simon Nickersons).
De cette façon, vous accédez à chaque élément exactement une fois pour un tableau de n éléments. Donnant ainsi une efficacité de O (n).
Utilisation de chaîne:
String abc = "abcd";
int a= abc.length();
String reverse="";
for (int i=a-1;i>=0 ;i--)
{
reverse= reverse + abc.charAt(i);
}
System.out.println("Reverse of String abcd using invert array is :"+reverse);
Utilisation de StringBuilder:
String abc = "abcd";
int a= abc.length();
StringBuilder sb1 = new StringBuilder();
for (int i=a-1;i>=0 ;i--)
{
sb1= sb1.append(abc.charAt(i));
}
System.out.println("Reverse of String abcd using StringBuilder is :"+sb1);
public static string getReverse(string str)
{
char[] ch = str.ToCharArray();
string reverse = "";
for (int i = str.Length - 1; i > -1; i--)
{
reverse += ch[i];
}
return reverse;
}
//using in-built method reverse of Array
public static string getReverseUsingBulidingFunction(string str)
{
char[] s = str.ToCharArray();
Array.Reverse(s);
return new string(s);
}
public static void Main(string[] args)
{
string str = "123";
Console.WriteLine("The reverse string of '{0}' is: {1}",str,getReverse(str));
Console.WriteLine("The reverse string of '{0}' is: {1}", str, getReverseUsingBulidingFunction(str));
Console.ReadLine();
}
Une variante peut être, permuter les éléments.
int n = length - 1;
char []strArray = str.toCharArray();
for (int j = 0; j < n; j++) {
char temp = strArray[j];
char temp2 = strArray[n];
strArray[j] = temp2;
strArray[n] = temp;
n--;
}
public static void main(String[] args){
String string ="abcdefghijklmnopqrstuvwxyz";
StringBuilder sb = new StringBuilder(string);
sb.reverse();
System.out.println(sb);
}
Utilisation de plusieurs threads pour échanger les éléments:
final char[] strArray = str.toCharArray();
IntStream.range(0, str.length() / 2).parallel().forEach(e -> {
final char tmp = strArray[e];
strArray[e] = strArray[str.length() - e - 1];
strArray[str.length() - e - 1] = tmp;
});
return new String(strArray);
Bien sûr, c’est le moyen le plus efficace:
String reversed = new StringBuilder(str).reverse().toString();
Mais si vous n'aimez pas utiliser cela, je vous recommande plutôt ceci:
public String reverseString(String str)
{
String output = "";
int len = str.length();
for(int k = 1; k <= str.length(); k++, len--)
{
output += str.substring(len-1,len);
}
return output;
}
public static String Reverse(String Word){
String temp = "";
char[] arr = Word.toCharArray();
for(int i = arr.length-1;i>=0;i--){
temp = temp+arr[i];
}
return temp;
}