4

私は、文字列をそれぞれ転置および転置解除する 2 つのメソッドに取り組んできました。私が思いついた解決策は、私の知る限りでは両方とも機能します。これらの問題をより簡単な方法で解決できたかどうかを知りたいだけです。私のコードは、実行中のタスクに対して長すぎるようです。最初のメソッド、transpose() は、パラメーターとして文字列を取り、それを転置します。「bridge」と入力すると、出力は「bergid」になります。同様に、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
4

8 に答える 8

4

再帰の使用

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);
    }
}
于 2010-04-13T12:24:27.360 に答える
3

このソリューションは対称性に優れています。

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

これにより、2 つのメソッド間のロジックが同一であることが明らかになります。唯一の違いは次のとおりです。

  • transposeijは読み取りインデックス、xは書き込みインデックスです。
  • ではuntransposeijは書き込みインデックスでxあり、 は読み取りインデックスです (つまり、その逆です)。

それは本当にとても簡単です:

  • i常に文字列の最初から途中まで
  • j常に文字列の最後から途中まで
  • x常に文字列の最初から最後まで
  • 入力の長さが奇数の場合、必然i == j的に最終的に
    • その時点で必要なのは だけなiので、break

Lalith は最初の再帰的な解決策を思いつきました。これは基本的に同じですが、わずかな変更があります。

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);
}
于 2010-04-13T03:25:11.563 に答える
1

これに対する私の回答は次のとおりです-コードで見た主な問題は、コードの複数の領域で一時オブジェクトとして文字列を作成していることです-これにより、非常に非効率的で非常に遅くなります。もう 1 つの問題は、ループからできることをすべて外部化することです。私はそれをコンパイルして実行しましたが、動作します。

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) ブリッジ

于 2010-04-13T03:08:06.477 に答える
0

通常、これらの種類の操作をより簡単にする 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() );
}

untranspose メソッドを自分で実装するのに十分なアイデアを提供する必要があります :+)

于 2010-04-13T03:12:51.357 に答える
0

これは、転置と非転置の間の対称性を示す別のソリューションです。

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);
}
于 2010-04-13T03:52:38.717 に答える
0

これは、文字列の長さが偶数か奇数かに基づいて異なる動作を必要としないメソッドです。

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();
}
于 2010-04-13T03:18:49.373 に答える
0

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();
}
于 2010-04-13T03:18:57.777 に答える
0

式は、理解するのが難しくなりすぎることなく、かなり短くすることができます。

/** 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);
}
于 2018-11-03T13:19:32.577 に答える