2012-01-08 15 views
4

私はJavaで簡単な暗号化プログラムをやっています。ユーザーが文字列(strTarget)を入力すると、その文字列がこの関数に渡されます。 forループでは、文字のASCII値を4にしてから文字列に戻す必要があります(文字列内のすべての文字についてこれを行います)。あなたが私の友人を見て、私はすでにそれを行っている、しかし、私は戻って(例えば、ユーザが 'efg'を入力した場合、返された文字列は 'abc'になる必要があります)文字列を返す方法

私が提案した結果は次のとおりです。私は明らかに何が間違ってメニュークラスでは、それが何であるかわからない。私は暗号化する文字列を入力すると動作を停止します。

import java.util.Scanner; 

public class Menu { 

public static String strTarget; 

public static void main(String[] args) { 


    Scanner in = new Scanner(System.in); 

    System.out 
      .println("Welcome to the encr/decr program"); 
    System.out 
      .println("To encrypt a string, press 1, to decrypt a string, press 2"); 
    int choice = in.nextInt(); 
    if (choice == 1) { 
     System.out.println("Type the string you want to encrypt."); 
     strTarget = in.next(); 
     System.out.println(Encrypt(strTarget)); 
    } 
    if (choice == 2) { 
     System.out.println("Enter the string you want to decrypt."); 
    } 

} 

private static String Encrypt(String strTarget) { 
    // TODO Auto-generated method stub 
    int len = strTarget.length()-1; 

    String destination = ""; 

    for (int i = 0; i<len; i++) 
    { 

     if (strTarget.charAt(i) != ' ') 
     { 
      char a = strTarget.charAt(i); 
      int b = (int) a; 
      b = strTarget.charAt(i)-4; 
      a = (char) b; 
      if (b<70 && b>64) 
      { 
       b = strTarget.charAt(i)+26; 
       a = (char) b; 

       destination += a; 
      } 
     } 


    } 
    return destination; 

}}

EDIT:完全なプログラムを追加しました。

import java.util.Scanner; 

public class Menu { 

public static String strTarget; 

public static String destination = ""; 

public static void main(String[] args) { 


Scanner in = new Scanner(System.in); 

System.out.println("Welcome to the encr/decr program"); 

System.out.println("To encrypt a string, press 1, to decrypt a string, press 2"); 



int choice = in.nextInt(); 

if (choice == 1) { 
    System.out.println("Type the string you want to encrypt."); 

    strTarget = in.next(); 

    StringBuilder zomg = new StringBuilder(strTarget); 

    System.out.println(Encrypt(zomg)); 


} 

if (choice == 2) { 
    System.out.println("Enter the string you want to decrypt."); 
} 

}

private static String Encrypt(StringBuilder zomg) { 
// TODO Auto-generated method stub 

int len = strTarget.length()-1; 

for (int i = 0; i<len; i++) 
{ 

    if (strTarget.charAt(i) != ' ') 
    { 
     char a = strTarget.charAt(i); 
     int b = (int) a; 
     b = strTarget.charAt(i)-4; 
     a = (char) b; 
     destination += a; 
     if (b<70 && b>65) 
     { 
      b = strTarget.charAt(i)+26; 
      a = (char) b; 
      destination += a; 
     } 
    } 


} 
System.out.println(destination); 
return destination; 

}}

は、私はあなたが(私が思う)と変更を加えて、それが仕事に始めるが、それがすることになっているとして、それが機能していません。意味が分からないような結果が得られます( 'A'の場合、 'V'の場合は戻って 'V'の場合)。助言がありますか?

答えて

2

変換された各文字をStringBuilderまたはStringBufferに追加するだけです。それを行うshoud

target += a; 

:この操作を行う場合には、内側に

String target = ""; 

+2

リリースJDK 5では、StringBufferには、単一のスレッドStringBuilder用に設計された同等のクラスが追加されました。 StringBuilderクラスは、同じ操作のすべてをサポートしますが、同期を実行しないため、より高速ですので、一般的にこれに優先して使用する必要があります。 http://docs.oracle.com/javase/6/docs/api/java/lang/StringBufferhtml – SHiRKiT

+1

最適なパフォーマンスを得るには、あらかじめわかっているように、適切な容量のストリングビルダを作成してください。 –

-1

は、forループの前に空の文字列を初期化します!

return target; 
+0

'StringBuilder'はこれよりも優先されるべきです。これは、メモリ内に多数のオブジェクトを作成し、入力が事前にわからないためです。 –

0
private static String Encrypt(String strTarget) { 
    // TODO Auto-generated method stub 
    int len = strTarget.length()-1; 

    String destination = ""; 

    for (int i = 0; i<len; i++) 
    { 

     if (strTarget.charAt(i) != ' ') 
     { 
      char a = strTarget.charAt(i); 
      int b = (int) a; 
      b = strTarget.charAt(i)-4; 
      a = (char) b; 
      if (b<70 && b>64) 
      { 
       b = strTarget.charAt(i)+26; 
       a = (char) b; 

       destination += a; 
      } 
     } 

    return destination; 
    } 

私は、destinationと呼ばれる新しい文字列を追加し、それに文字を追加し、それを返しました。

EDIT

しかし、あなたが実際StringstrTarget変更することと思われます。そうするには

そのpasses it by value rather than by reference.

が実際に文字列を変更するので、あなたはhere概説として、StringBuilderを渡し、あなたのパラメータとしてstrTargetを渡すべきではありません。 ( "ここ" によって、リンクです。)

EDIT#2

は、あなたがメソッドを持っていると言います。それをfooと呼んでください。fooがパラメータとしてintを取り、1に設定します:

public static void foo(int i) { 
    i = 1; 
} 

今すぐあなたのメソッドをテストしたい:

public static void main(String[] args) { 

    int i = 0; 
    foo(i); 
    System.out.println(i); 
} 

は、これは右、1をプリントアウトする必要がありますか? なし。それはしません。それは"0"を印刷します。あなたが望めばそれをテストすることができます。 整数がで「値渡し」であるためです。何かが値渡しされると、仮想マシンは基本的にそのコピーを作成し、コピーをメソッドに渡します。あなたはfoo方法でi=1を実行するとき

したがって、あなたが実際に1、ないiiのコピーを設定しています。したがってiは変更されません。

と呼ばれる別のタイプのパラメータ渡しが、を通過します。何かが参照渡しされると、メソッドは実際の変数を変更します。

たとえば、配列は参照渡しされます。例えば、このコードを取る:それは参照によって渡されるよう

public static void foo(int[] i) { 
    i[0] = 1; // i must have at least one element. 
} 


public static void main(String[] args) { 

    int[] i = new int[1]; 
    foo(i); 
    System.out.println(i[0]); 
} 

この例では、iは、fooに修正されます。

元の方法では、戻り値の型をvoidとします。戻り値の型がvoidの場合、暗号化されたStringを返すことはできません。それで、参考にしてstrTarget自体を修正したいと思ったのかもしれません。

これを行うには、strTargetを渡す代わりにStringBuilderを渡します。 new StringBuilder(strTarget)で作成すると自動的にpass by referenceとなります。これを望むなら、destinationString(上記のとおり)を生成し、strTargetdestinationStringに変更するようにStringBuilderを変更します。

私はこれが助けてくれることを願っています。

+0

その編集は私に頭痛を与えましたが、それは私が最終的に私を助けるだろうと信じています。私はあなたが話していることを理解できないことが明らかであるように、StringBuilderの読み方や文字列の変更方法についてもっと詳しくお試しになります: – speci

+0

@speci質問を編集してより分かりやすくします。 – eboix

+0

これは今編集されました。 – eboix

0

あなたは次のように何かをしようとする場合があります。ここでは

private static String encrypt(String strTarget) { 
    char[] chars = strTarget.toCharArray(); 
    for(int i=0; i<chars.length; i++) { 
     if(chars[i] != ' ') { 
      int asciiVal = chars[i]; 
      asciiVal -= 4; 
      if(asciiVal < 70 && asciiVal > 64) { 
       asciiVal += 26;      
      } 
      chars[i] = (char) asciiVal; 
     } 
    } 
    return String.valueOf(chars); 
} 
2

は、再帰的なソリューションです。

あなたはEncrypt(string,0)

private static String Encrypt(String strTarget, int place) { 
// TODO Auto-generated method stub 
    if (place==strTarget.length()) { 
     return strTarget; 
    } 
    if (strTarget.charAt(place) != ' ') 
    { 
     char a = strTarget.charAt(place); 
     int b = (int) a; 
     b = strTarget.charAt(place)-4; 
     a = (char) b; 
     if (b<70 && b>64) 
     { 
      b = strTarget.charAt(place)+26; 
      a = (char) b; 
     } 
     return Encrypt(strTarget.substring(0,place)+a+strTarget.substring(place+1,strTarget.length()),place+1); 
    } 
    return null; 
} 
+1

それは過密ではありませんか?+1 – eboix

+2

。私のために気になった。 – schwert

0

読み取り可能な、より多くのオブジェクト指向のバージョンでそれを呼びたいですいくつかのキャラクターマジックを使用:

private static final int MOD_ALPHABET = 'Z' - 'A' + 1; 

private static String rot(int rot, String toEncrypt) { 

    int rangedRot = rot % MOD_ALPHABET; 
    if (rangedRot < 0) { 
     rangedRot = MOD_ALPHABET + rangedRot; 
    } 

    final StringBuilder sb = new StringBuilder(toEncrypt); 
    for (int i = 0; i < sb.length(); i++) { 
     final char plainChar = sb.charAt(i); 
     final char startChar; 
     if (plainChar >= 'A' && plainChar <= 'Z') { 
      startChar = 'A'; 
     } else if (plainChar >= 'a' && plainChar <= 'z') { 
      startChar = 'a'; 
     } else { 
      continue; 
     } 

     char cryptChar = (char) (plainChar - startChar); 
     cryptChar += rangedRot; 
     cryptChar %= MOD_ALPHABET; 
     cryptChar += startChar; 
     sb.setCharAt(i, cryptChar); 
    } 
    return sb.toString(); 
} 
関連する問題