Подтвердить что ты не робот

Каков наиболее эффективный алгоритм для обращения к String в Java?

Каков наиболее эффективный способ изменить строку на Java? Должен ли я использовать какой-то оператор xor? Легким способом было бы положить все символы в стек и снова вернуть их в строку, но я сомневаюсь, что это очень эффективный способ сделать это.

И, пожалуйста, не говорите мне использовать какую-либо встроенную функцию в Java. Мне интересно узнать, как сделать это, чтобы не использовать эффективную функцию, но не зная, почему она эффективна или как она создана.

4b9b3361

Ответ 1

Вы говорите, что хотите узнать наиболее эффективный способ, и вы не хотите знать какой-то стандартный встроенный способ сделать это. Тогда я говорю вам: RTSL (читайте источник, luke):

Проверьте исходный код AbstractStringBuilder # reverse, который вызывается StringBuilder # reverse. Бьюсь об заклад, это делает некоторые вещи, которые вы бы не рассмотрели для надежной обратной операции.

Ответ 2

Ниже не рассматриваются суррогатные пары 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);
}

Ответ 3

Вы сказали, что не хотите делать это легко, но для тех, кто использует Google, вы должны использовать StringBuilder.reverse:

String reversed = new StringBuilder(s).reverse().toString();

Если вам нужно реализовать его самостоятельно, перейдите по символам в обратном порядке и добавьте их в StringBuilder. Вы должны быть осторожны, если есть (или могут быть) суррогатные пары, поскольку они не должны быть отменены. Вышеуказанный метод делает это автоматически, поэтому вы должны использовать его, если это возможно.

Ответ 4

Старый пост и вопрос, однако, не видели ответов, относящихся к рекурсии. Рекурсивный метод реверсирует данную строку s, не передавая встроенные функции jdk

    public static String reverse(String s) {
    if (s.length() <= 1) {
        return s;
    }
    return reverse(s.substring(1)) + s.charAt(0);
}

`

Ответ 5

Самый быстрый способ - использовать метод reverse() для классов StringBuilder или StringBuffer:)

Если вы хотите реализовать его самостоятельно, вы можете получить массив символов, выделить второй массив символов и переместить символы, в псевдокоде это будет выглядеть так:

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

Вы также можете запустить половину длины массива и поменять символы, проверки, вероятно, замедляют работу.

Ответ 6

Я не совсем уверен, что вы имеете в виду, когда говорите, что вам нужен эффективный алгоритм.

Способы изменения строки, о которой я могу думать (все они уже упоминаются в других ответах):

  • Используйте стек (ваша идея).

  • Создайте новую переменную String, добавив символы по порядку в обратном порядке от исходной строки к пустой строке String/StringBuilder/ char [].

  • Обменивать все символы в первой половине строки с ее соответствующей позицией в последней половине (т.е. i-й символ обменивается с (длиной-i-1) -им символом).

Дело в том, что все они имеют одинаковую сложность выполнения: O (N). Таким образом, на самом деле нельзя утверждать, что любой из них значительно лучше других для очень больших значений N (т.е. очень больших строк).

У третьего метода есть что-то для этого, другие два требуют O (N) дополнительного пространства (для стека или новой строки), тогда как он может выполнять свопы. Но Строки неизменны в Java, поэтому вам нужно выполнить свопы на вновь созданной StringBuilder/ char [], и, таким образом, вам нужно дополнительное пространство O (N).

Ответ 7

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

    }
}

Ответ 8

Я думаю, что если у вас ДЕЙСТВИТЕЛЬНО нет проблем с производительностью, вы должны просто пойти с самым читаемым решением, которое:

StringUtils.reverse("Hello World");

Ответ 9

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

Ответ 10

Если вы не хотите использовать какую-либо встроенную функцию, вам нужно вернуться со строкой к ее составным частям: массив символов.

Теперь вопрос становится наиболее эффективным способом обращения к массиву? Ответ на этот вопрос на практике также зависит от использования памяти (для очень больших строк), но теоретически эффективность в этих случаях измеряется в доступе к массиву.

Самый простой способ - создать новый массив и заполнить его значениями, которые вы встречаете при обратном итерации по исходному массиву, и возврату нового массива. (Хотя с временной переменной вы также можете сделать это без дополнительного массива, как в ответе Саймона Никерсона).

Таким образом вы получаете доступ к каждому элементу ровно один раз для массива с n элементами. Таким образом, получается эффективность O (n).

Ответ 11

Я бы просто сделал это без использования какой-либо одной функции утилиты. Достаточно класс String.

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

Проверьте это. Ура!!

Ответ 12

Использование строки:

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

Использование 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);

Ответ 13

Один вариант может быть, заменяя элементы.

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

Ответ 14

public static void main(String[] args){
    String string ="abcdefghijklmnopqrstuvwxyz";
    StringBuilder sb = new StringBuilder(string);
    sb.reverse();

    System.out.println(sb);
}

Ответ 15

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

Ответ 16

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

=========================

Хотите узнать, как это работает?

Первая операция:

x1 = x1 XOR x2

x1: 1   0   0
x2: 1   1   1
New x1: 0   1   1

Вторая операция

x2 = x2 XOR x1

x1: 0   1   1
x2: 1   1   1
New x2: 1   0   0
//Notice that X2 has become X1 now

Третья операция:

x1 = x1 XOR x2
x1: 0   1   1
x2: 1   0   0
New x1: 1   1   1
//Notice that X1 became X2

Ответ 17

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

Ответ 18

Использование нескольких потоков для замены элементов:

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

Ответ 19

Конечно это самый эффективный способ:

String reversed = new StringBuilder(str).reverse().toString();

Но если вам не нравится это, я рекомендую это:

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

Ответ 20

static String ReverseString(String input) {
    var len = input.Length - 1;
    int i = 0;
    char[] revString = new char[len+1];
    while (len >= 0) {
        revString[i] = input[len];
        len--; 
        i++;
    }
    return new string(revString);   
}

почему мы не можем придерживаться простейшего цикла и почитать с чтением символов и продолжать добавлять в массив символов, я наткнулся на интервью с доской, где интервьюер установил ограничения на то, чтобы не использовать StringBuilder и встроенные функции.

Ответ 21

public static String reverseString(String str)
{
    StringBuilder sb = new StringBuilder();

    for (int i = str.length() - 1; i >= 0; i--)
    {
        sb.append(str[i]);
    }

    return sb.toString();
}