【问题标题】:Method to return string返回字符串的方法
【发布时间】:2012-02-05 15:15:03
【问题描述】:

所以我正在用 Java 做一个简单的加密程序。用户输入一个字符串 (strTarget),然后将该字符串带到此函数。在 for 循环中,它应该获取字符的 ASCII 值,将其减少 4,然后将其返回到字符串(对字符串中的所有字符都这样做)。正如你看到我的朋友,我已经这样做了,但是,我不确定如何重建我希望返回的字符串(例如,如果用户输入'efg',返回的字符串应该是'abc')

所以,这是我根据建议得到的结果。我显然在 Menu 类中做错了什么,不确定它是什么。当我输入要加密的字符串时它停止工作。

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; 

} }

编辑:添加了完整的程序。

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')。有什么建议吗?

【问题讨论】:

    标签: java encryption


    【解决方案1】:

    只需将每个转换后的字符附加到StringBuilderStringBuffer

    【讨论】:

    • 从 JDK 5 开始,StringBuffer 已经补充了一个为单线程使用而设计的等效类 StringBuilder。通常应优先使用 StringBuilder 类,因为它支持所有相同的操作,但速度更快,因为它不执行同步。 docs.oracle.com/javase/6/docs/api/java/lang/StringBuffer.html
    • 为了获得最佳性能,请创建一个具有正确容量的字符串生成器,无论如何您都事先知道它。
    【解决方案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
    【解决方案3】:

    您可能想尝试以下方法:

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

    【讨论】:

      【解决方案4】:
      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 的新字符串,将字符添加到其中,然后返回它。

      编辑

      不过,您似乎需要修改实际的StringstrTarget

      为此,您不应将 strTarget 作为参数传递,因为 passes it by value rather than by reference.

      要实际修改字符串,请传递StringBuilder,如here 所述。 (顺便说一下,“这里”是一个链接。)

      编辑#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 时,您实际上是将i 的副本设置为1,而不是i。所以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]);
      }
      

      在此示例中,ifoo 中进行了修改,因为它是通过引用传递的。

      在您的原始方法中,您将返回类型设置为void。如果返回类型为 void,则无法返回加密的 String。所以我突然想到,也许你想通过引用传递并修改strTarget 本身。

      为此,您可以传递StringBuilder,而不是传递strTarget。您可以使用new StringBuilder(strTarget) 创建它,它会自动pass by reference。如果你想要这个,那么我会做的是生成destinationString(如上所述),然后修改StringBuilder以将strTarget更改为destinationString

      我希望这会有所帮助。

      【讨论】:

      • 那个编辑让我头疼,但我相信它最终会帮助我。我将尝试对 StringBuilder 以及如何修改字符串进行更多阅读,因为很明显我无法理解您在说什么:(
      • 我按照你说的更新了代码,朋友,但是它没有返回想要的结果:(我想我在那里做错了什么..
      【解决方案5】:

      使用一些字符魔法的可读、更面向对象的版本:

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

      【讨论】:

        【解决方案6】:

        在for循环之前初始化一个空字符串:

        String target = "";
        

        在内部如果这样做:

        target += a;
        

        应该这样做!

        return target;
        

        【讨论】:

        • StringBuilder 应该优先于这个,因为这会在内存中创建大量对象,并且事先不知道输入。
        猜你喜欢
        • 1970-01-01
        • 2020-04-13
        • 2023-03-30
        • 1970-01-01
        • 2015-06-09
        • 2012-05-19
        • 2016-05-19
        • 1970-01-01
        相关资源
        最近更新 更多