Транспонирование и нетранспонирование строки в Java - PullRequest
4 голосов
/ 13 апреля 2010

Я работал над двумя методами, которые будут Transpose и Untranspose a String соответственно. Решения, которые я придумала, работают в меру моих знаний. Я просто хочу знать, смог бы я решить эти проблемы более простым способом. Мой код кажется слишком длинным для выполняемой задачи. Первый метод, transpose (), примет String в качестве параметра и транспонирует его. Если введен «мост», вывод будет «бергидным». Аналогично, с помощью метода unTranspose (), если пользователь вводит «bergid», вывод будет «bridge».

  public void transpose( String s )
  {
      String t = ""; 
      int end = s.length() - 1;


        for ( int i = 0; i < s.length()  / 2; i++ )
        {
            t += Character.toString( s.charAt( i ) ) + Character.toString( s.charAt( end ) );
            end--;
        }
        // Lenth of String is odd
        if ( s.length() % 2 == 1 )
        {
            // add character in middle of String to the end of the new String
            t+= Character.toString( s.charAt( s.length() / 2 ) );
        }

        System.out.println( t );
  }

    public void unTranspose( String s )
    {
    String t = ""; 

      // Length of String is odd
      if ( s.length() % 2 == 1 )
      {
      for ( int i = 0; i < s.length(); i+=2 )
      {
        t+= Character.toString( s.charAt( i ) );
      }

      for ( int i = s.length() - 2; i > 0; i -= 2 )
      {
        t += Character.toString( s.charAt( i ) );
      }

         System.out.println( t );
      }



   // Length of String is even
   else if ( s.length() % 2 == 0 )
   {
    for ( int i = 0; i < s.length() - 1; i+=2 )
    {
       t+= Character.toString( s.charAt( i ) );
    }

    for ( int i = s.length() - 1; i > 0; i -= 2 )
    {
        t+= Character.toString( s.charAt( i ) );
    }


    System.out.println( t );
}
   }

Мой код выглядит ужасно. Я до сих пор не привык правильно форматировать свой код. Пожалуйста, потерпите меня.

Спасибо за ваше время


Определение

         transpose
         --------->
"123Xcba"            "1a2b3cX"
        <-----------
        untranspose

Ответы [ 8 ]

4 голосов
/ 13 апреля 2010

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

public static String transpose(String str) {

    if (str == null || str.length() == 1 || str.length() == 2) {
        return str;
    } else {
        return str.substring(0, 1) + str.substring(str.length() -1, str.length()) + transpose(str.substring(1, str.length() -1) );
    }
}

public static String untranspose(String str) {
    if (str == null || str.length() == 1 ||str.length() == 2) {
        return str;
    } else {
        return  str.substring(0, 1) + untranspose(str.substring(2, str.length())) + str.substring(1, 2);
    }
}
3 голосов
/ 13 апреля 2010

Это решение имеет хорошую симметрию.

public static String transpose(String s) {
    StringBuilder sb = new StringBuilder();
    sb.setLength(s.length());
    for (int i = 0, j = s.length() - 1, x = 0; i <= j; ) {
        sb.setCharAt(x++, s.charAt(i++));
        if (i > j) break;
        sb.setCharAt(x++, s.charAt(j--));
    }
    return sb.toString();
}

public static String untranspose(String s) {
    StringBuilder sb = new StringBuilder();
    sb.setLength(s.length());
    for (int i = 0, j = s.length() - 1, x = 0; i <= j; ) {
        sb.setCharAt(i++, s.charAt(x++));
        if (i > j) break;
        sb.setCharAt(j--, s.charAt(x++));
    }
    return sb.toString();
}

Это делает очевидным, что логика между двумя методами идентична ; единственная разница в том, что:

  • В transpose, i и j - индексы чтения, x - индекс записи
  • В untranspose, i и j - индексы записи, x - индекс чтения (т.е. наоборот)

Это действительно довольно просто:

  • i всегда идет от начала до середины строки
  • j всегда идет от конца до середины строки
  • x всегда идет от начала до конца строки
  • Если ввод нечетной длины, неизбежно i == j в конце концов
    • На данный момент вам нужно только i, поэтому break

Лалит придумала первое рекурсивное решение ; этот по сути тот же самый, с незначительной модификацией:

public static String transpose(String s) {
  int L = s.length();
  return (L < 2) ? s
    : s.substring(0, 1) + s.substring(L-1, L) + transpose(s.substring(1, L-1));
}

public static String untranspose(String s) {
  int L = s.length();
  return (L < 2) ? s
    : s.substring(0, 1) + untranspose(s.substring(2, L)) + s.substring(1, 2);
}
1 голос
/ 13 апреля 2010

Вот мой ответ на этот вопрос. Основная проблема, с которой я столкнулся в вашем коде, заключается в том, что вы создаете строки как временные объекты в нескольких областях кода. Это делает его очень неэффективным, а также очень медленным. Другая проблема заключается в том, что вы хотите вывести из цикла все, что можете. Я скомпилировал его и запустил, и он работает.

package com.rch.test;

public class Transposer
{
    public static String transpose(String s)
    {
        int length = s.length();
        int end = length - 1;

        StringBuilder t = new StringBuilder();
        for (int i = 0; i < length / 2; i++)
        {
            t.append(s.charAt(i));
            t.append(s.charAt(end));
            end--;
        }

        // Length of String is odd
        if (length % 2 == 1)
        {
            // add character in middle of String to the end of the new String
            t.append(s.charAt(length / 2));
        }
        return t.toString();
    }

    public static String unTranspose(String s)
    {
        int length = s.length();
        StringBuilder t = new StringBuilder();

        if (length % 2 == 1)
        {
            for (int i = 0; i < length; i += 2)
            {
                t.append(s.charAt(i));
            }

            for (int i = length - 2; i > 0; i -= 2)
            {
                t.append(s.charAt(i));
            }
        }
        else if (length % 2 == 0)
        {
            for (int i = 0; i < length - 1; i += 2)
            {
                t.append(s.charAt(i));
            }

            for (int i = length - 1; i > 0; i -= 2)
            {
                t.append(s.charAt(i));
            }
        }
        return t.toString();
    }

    public static void main(String[] args)
    {
        String testString = "bridge";
        String transposedString = Transposer.transpose(testString); 
        String finalString = Transposer.unTranspose(transposedString);

        System.out.println("1)" + testString);
        System.out.println("2)" + transposedString);
        System.out.println("3)" + finalString);
    }
}

Выход: 1) мост 2) bergid 3) мост

0 голосов
/ 03 ноября 2018

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

/** Convert ABCDefg to AgBfCeD */
public static String transpose(String s){
    char[] ts = new char[s.length()];
    int i = 0, j = ts.length;
    for( int k = 0 ; k < ts.length ; k++ ){
        ts[k] = s.charAt(k%2==0 ? i++ : --j);
    }
    return new String(ts);
}
/** Convert AgBfCeD to ABCDefg */
public static String untranspose(String ts){
    char[] s = new char[ts.length()];
    int i = 0, j = ts.length();
    for( int k = 0 ; k < ts.length() ; k++ ){
        s[k%2==0 ? i++ : --j] = ts.charAt(k);
    }
    return new String(s);
}
0 голосов
/ 13 апреля 2010

Вот еще одно решение, которое показывает симметрию между транспонированием и нетранспонированием.

public static String transpose(String in)
{
    int length = in.length();
    StringBuilder out = new StringBuilder(in);
    for (int pos=1; pos<length; pos+=2)
    {
        swapCharacters(out, length-1, pos);
    }
    return out.toString();
}

public static String untranspose(String in)
{
    int length = in.length();
    StringBuilder out = new StringBuilder(in);
    for (int pos=length-1-(length%2); pos>0; pos-=2)
    {
        swapCharacters(out, pos, length-1);
    }
    return out.toString();
}

private static void swapCharacters(StringBuilder string, int oldPos, int newPos)
{
    char c = string.charAt(oldPos);
    string.deleteCharAt(oldPos);
    string.insert(newPos, c);
}
0 голосов
/ 13 апреля 2010

Ну, я смог немного упростить метод transpose:

public static String transpose(String s)
{
   StringBuilder sb = new StringBuilder();
   int i = 0;
   int length = s.length() - 1;
   while(i < length - i)
   {
      sb.append(s.charAt(i)).append(s.charAt(length - i));
      i++;
   }
   if(i == length - i) sb.append(s.charAt(i));
   return sb.toString();
}

Обновление

Испытал мою удачу с неперемещением -

public static String untranspose(String s)
{
   StringBuilder sb1 = new StringBuilder();
   StringBuilder sb2 = new StringBuilder();
   int length = s.length();
   int iopp = (length % 2 == 0) ? length - 1 : length - 2;
   for(int i = 0; i < length; i += 2, iopp -= 2)
   {
      sb1.append(s.charAt(i));
      if(iopp >= 0) sb2.append(s.charAt(iopp));
   }
   return sb1.append(sb2).toString();
}
0 голосов
/ 13 апреля 2010

Вот метод, который не требует другого поведения в зависимости от того, является ли длина строки четной или нечетной.

public static String transpose(String in)
{
    StringBuilder out = new StringBuilder();
    for (int i=0; i<in.length(); ++i)
    {
        out.append(in.charAt(i));
        out.append(in.charAt(in.length() - i - 1));
    }
    return out.substring(0, in.length());
}

public static String untranspose(String in)
{
    StringBuilder out = new StringBuilder();
    for (int i=0; i<in.length(); i+=2)
    {
        out.append(in.charAt(i));
    }
    StringBuilder reversedSecondHalf = new StringBuilder();
    for (int i=1; i<in.length(); i+=2)
    {
        reversedSecondHalf.append(in.charAt(i));
    }
    out.append(reversedSecondHalf.reverse());
    return out.toString();
}
0 голосов
/ 13 апреля 2010

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

public static void transpose( String s ) 
{
    StringBuilder sb = new StringBuilder(s);

    for( int i=1; i<sb.length(); i=i+2 ) {          
        sb.insert( i, sb.charAt( sb.length()-1 ) );         
        sb.deleteCharAt( sb.length()-1 );
    }

    System.out.println( sb.toString() );
}

Должно дать вам достаточно идей для самостоятельной реализации нетранспонированного метода: +)

...