我的目标是返回一个字符串,该字符串由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"。有人能指出我正确的方向吗?真的很难过了。
答案 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));
}
}
就是这样:
通过将案例表示为模式匹配语句,某些语言(如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));
}
}
这里的主要观点是:
答案 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