如何计算上一个和下一个字符?

时间:2016-03-21 16:30:01

标签: java string

我的目标是返回一个字符串,该字符串由ASCII表中给定字符串中每个字符前1​​和后1的字符组成。

例如,dog应该返回cenpfh

public String encrypt(String s) {
   if (s.length() == 1) {
       String one = "";
       one += (s.charAt(0)-1) + (s.charAt(0)+1);
       return one;
   } else { .. }
}

这是我到目前为止的代码,我不知道如何继续。这甚至不适用于单个角色,例如," 172"返回" V"。有人能指出我正确的方向吗?真的很难过了。

5 个答案:

答案 0 :(得分:3)

不需要递归。只需迭代输入字符并在StringBuilder

中收集结果
public static String encrypt(String s) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);
        sb.append((char)(c - 1)).append((char)(c + 1));
    }
    return sb.toString();
}

请注意,此处需要显式转换为char,因为s.charAt(i) - 1评估为int而没有强制转换是由重载的append(int i)方法处理的。

好的,递归。在这里,我将输入分成两半并使用相同的encryptRecursively()方法处理每个,然后连接结果。当传递给方法时,每个部分再次分成两部分等,直到大小变为0或1(因此我们得到Divide and Conquer的非常简单的实现):

public static String encryptRecursively(String s) {
    if (s.isEmpty())
        return "";
    else if (s.length() == 1) {
        char c = s.charAt(0);
        return new String(new char[] { (char)(c - 1), (char)(c + 1) });
    } else {
        int mid = s.length() / 2;
        return encryptRecursively(s.substring(0, mid)) // process first half of input
             + encryptRecursively(s.substring(mid));   // second half
    }
}

答案 1 :(得分:3)

这对于初学者来说是相当棘手的事情,但这是早期遇到并理解的好东西。

"" + 172

产生字符串“172”

"" + 'V'

产生字符串“V”。

V和172都在内部表示为相同的数字,那么有什么区别?不同之处在于编译器会跟踪值的类型。 'V'的类型为char。 172的类型为int

使用混合类型执行表达式时,编译器必须确定结果的类型。这将影响字符串连接等例程处理结果的方式。

当你从char中减去一个int时,结果的类型是一个int(Java规范告诉你)。

您可以通过类型转换为其他内容来解决此问题。

  • (char) 172是'V'
  • (int) 'V'是172。

所以:

  one += (char) (s.charAt(0)-1) + (char)(s.charAt(0)+1);

递归是一个单独的主题。递归适用于处理序列(String是一系列字符),当你可以在序列的一部分上做一大块工作时,给你一个新的,更短的序列,你可以做同样的工作 - 直到最后你有最简单的情况,你只需返回。

最简单的情况是,方法在没有递归调用自身的情况下返回的情况称为终止情况。您至少需要一个终止案例,否则递归方法将一直调用自己,直到Java内存不足以存储方法状态。

您已选择终止案例为一个字符串。我会选择一个零长度的字符串:

 public void encrypt(String s) {
     if("".equals(s)) {
         return "";
     } else {
         // do something with a string that's guaranteed >1 char
     }

现在你只需要弄清楚如何替换那个评论,通过使用保证的一个字符,并调用encrypt()来处理剩下的内容。

 public void encrypt(String s) {
     if("".equals(s)) {
         return "";
     } else {
         return encodeOneChar(s.charAt(0)) +
              encrypt(x.substring(1));
     }
 }

就是这样:

  • 当使用空字符串调用时,encode()返回一个空字符串。
  • 当使用非空字符串调用时,encode处理第一个char    并且要求自己处理一个更短的字符串。

通过将案例表示为模式匹配语句,某些语言(如Haskell)使递归更容易理解。

encrypted "" == ""
encrypted s == encryptChar(head(s)) + encrypted(tail(s))

(这不是真正的Haskell,但它说明了模式。)

递归在Java中读起来不是那么容易,但模式仍然存在。 if(terminating case) { return answer for terminating case } else { calculate something, call self, return combined result }

我会让你实施private String encodeOneChar(char c)

请注意,递归不是Java中实际任务的良好解决方案 - 除非您的目标是理解递归。

答案 2 :(得分:3)

如果你必须使用递归,你可以尝试这样的事情:

public static String encrypt(final String s) {
    if (s.length() == 1) {
        final char c = s.charAt(0);
        return new String(new char[] {(char) (c - 1), (char) (c + 1)});
    } else {
        return encrypt(s.substring(0, 1)) + encrypt(s.substring(1));
    }
}

这里的主要观点是:

  1. 如果输入长度是1个符号 - 我们知道该怎么做,只是执行&#34;加密&#34;
  2. 如果输入长度超过1个符号 - 我们将字符串拆分为&#34;第一个符号&#34;和&#34;其余的字符串&#34;并在两个部分自称“

答案 3 :(得分:1)

你不需要递归,而是通过单词中所有字符的简单for-loop。您可以使用s.charAt(...)获取char的值,但是您必须将其转换回char以获得所需的resut。将它们附加到StringBuilder并返回其String作为方法的输出:

public static String encrypt(String s) {      
    StringBuilder sb = new StringBuilder();
    for (int i=0; i<s.length(); i++) {
        char a = (char)(s.charAt(i)-1);
        char b = (char)(s.charAt(i)+1);
        sb.append(a).append(b);
    }
    return sb.toString();
}

这是需要的递归方法:

public static String encrypt(String s) {
    if (s.length() == 1) {
        StringBuilder sb = new StringBuilder();
        char a = (char)(s.charAt(0)-1);
        char b = (char)(s.charAt(0)+1);        
        return sb.append(a).append(b).toString();
    } else {
        return encrypt(s.substring(0, 1)) + encrypt(s.substring(1, s.length()));
}

答案 4 :(得分:0)

你可以试试这个:

one += (char)(((int)s.charAt(0))-1);
one += (char)(((int)s.charAt(0))+1);

输入:

  

V

输出:

  

UW