使用递归反转句子中的单词而不是标点符号
Reverse the words in a sentence but not punctuation using recursion
如何使用递归反转句子中的单词,而不是标点符号。据说该句使用标点符号:,.?!
输入:“杰克,回家吧!”
输出:“回家,杰克来了!”
现在我以某种方式设法正确地完成了任务,但没有使用递归。
我应该如何将这项工作转换为使用递归来解决问题?
方法如下:
public static StringBuilder reverseSentenceWithPunctuation(String sentence, int i) {
String[] parts = sentence.split(" ");
StringBuilder newSentence = new StringBuilder();
Map<Integer, Character> punctuationMap = new HashMap<>();
for (int j = 0; j < parts.length; j++) {
if (parts[j].endsWith(",") || parts[j].endsWith(".") || parts[j].endsWith("!") || parts[j].endsWith("?")) {
char lastSymbol = parts[j].charAt(parts[j].length()-1);
punctuationMap.put(j, lastSymbol);
String changedWord = parts[j].replace(String.valueOf(lastSymbol), "");
parts[j] = changedWord;
}
}
for (int j = parts.length-1; j >= 0; j--) {
newSentence.append(parts[j]);
if (punctuationMap.containsKey(i)) {
newSentence.append(punctuationMap.get(i));
newSentence.append(" ");
} else
newSentence.append(" ");
i++;
}
return newSentence;
}
提前致谢!
我认为这不是递归函数的好例子,主要是因为你需要 2 个循环。另外,一般来说,迭代算法在性能方面更好,不会抛出 Whosebug 异常。
所以我认为使用递归函数的主要原因是可读性和易用性,老实说,在这种情况下,我认为这是不值得的。
无论如何,这是我将您的代码转换为递归函数的尝试。如前所述,由于有 2 个循环,我使用了 2 个函数。我确信有一种方法可以通过一个函数实现这一点,该函数首先加载标点符号映射,然后组成最终字符串,但老实说,这会很丑陋。
import java.util.*;
import java.util.stream.*;
public class HelloWorld{
static Character[] punctuationCharacters = {',','.','!'};
public static void main(String []args){
System.out.println(reverseSentenceWithPunctuation("Jack, come home!"));
}
private static String reverseSentenceWithPunctuation(String sentence) {
String[] parts = sentence.split(" ");
return generate(0, parts, extractPunctuationMap(0, parts));
}
private static Map<Integer, Character> extractPunctuationMap(int index, String[] parts){
Map<Integer, Character> map = new HashMap<>();
if (index >= parts.length) {
return map;
}
char lastSymbol = parts[index].charAt(parts[index].length() - 1);
if (Arrays.stream(punctuationCharacters).anyMatch(character -> character == lastSymbol)) {
parts[index] = parts[index].substring(0, parts[index].length() - 1);
map = Stream.of(new Object[][] {
{ index, lastSymbol}
}).collect(Collectors.toMap(data -> (Integer) data[0], data -> (Character) data[1]));
}
map.putAll(extractPunctuationMap(index + 1, parts));
return map;
}
private static String generate(int index, String[] parts, Map<Integer, Character> punctuationMap) {
if (index >= parts.length) {
return "";
}
String part = index == 0? " " + parts[index] : parts[index];
if (punctuationMap.containsKey(parts.length -1 - index)) {
part += punctuationMap.get(parts.length -1 - index);
}
return generate(index + 1, parts, punctuationMap) + part;
}
}
在伪代码中可能是这样的:
- 取整句
(一)。得到第一个字
(b)。硬道理
(如果第一个或最后一个单词后有标点符号,请留在那里)
- swap(a, b) and return 剩下的句子中间
- 重复(1)和(2)直到只有两个词或一个
- return 剩下的最后两个(交换的)单词(如果是一个单词,就 return 那个)
要使用递归实现此任务,应准备一个匹配第一个和最后一个单词并后跟一些定界符的模式:
word1 del1 word2 del2 .... wordLast delLast
在匹配输入的情况下,结果计算为:
wordLast del1 REVERT(middle_part) + word1 delLast
实现示例可能如下(单词被认为包含英文字母和撇号'
用于缩写):
static Pattern SENTENCE = Pattern.compile("^([A-Za-z']+)([^A-Za-z]+)?(.*)([^'A-Za-z]+)([A-Za-z']+)([^'A-Za-z]+)?$");
public static String revertSentence(String sentence) {
Matcher m = SENTENCE.matcher(sentence);
if (m.matches()) {
return m.group(5) + (m.group(2) == null ? "" : m.group(2))
+ revertSentence(m.group(3) + m.group(4)) // middle part
+ m.group(1) + (m.group(6) == null ? "" : m.group(6));
}
return sentence;
}
测试:
System.out.println(revertSentence("Jack, come home!"));
System.out.println(revertSentence("Jack, come home please!!"));
System.out.println(revertSentence("Jane cried: Will you come home Jack, please, don't go!"));
输出:
home, come Jack!
please, home come Jack!!
go don't: please Jack home come you, Will, cried Jane!
如何使用递归反转句子中的单词,而不是标点符号。据说该句使用标点符号:,.?!
输入:“杰克,回家吧!”
输出:“回家,杰克来了!”
现在我以某种方式设法正确地完成了任务,但没有使用递归。 我应该如何将这项工作转换为使用递归来解决问题?
方法如下:
public static StringBuilder reverseSentenceWithPunctuation(String sentence, int i) {
String[] parts = sentence.split(" ");
StringBuilder newSentence = new StringBuilder();
Map<Integer, Character> punctuationMap = new HashMap<>();
for (int j = 0; j < parts.length; j++) {
if (parts[j].endsWith(",") || parts[j].endsWith(".") || parts[j].endsWith("!") || parts[j].endsWith("?")) {
char lastSymbol = parts[j].charAt(parts[j].length()-1);
punctuationMap.put(j, lastSymbol);
String changedWord = parts[j].replace(String.valueOf(lastSymbol), "");
parts[j] = changedWord;
}
}
for (int j = parts.length-1; j >= 0; j--) {
newSentence.append(parts[j]);
if (punctuationMap.containsKey(i)) {
newSentence.append(punctuationMap.get(i));
newSentence.append(" ");
} else
newSentence.append(" ");
i++;
}
return newSentence;
}
提前致谢!
我认为这不是递归函数的好例子,主要是因为你需要 2 个循环。另外,一般来说,迭代算法在性能方面更好,不会抛出 Whosebug 异常。
所以我认为使用递归函数的主要原因是可读性和易用性,老实说,在这种情况下,我认为这是不值得的。
无论如何,这是我将您的代码转换为递归函数的尝试。如前所述,由于有 2 个循环,我使用了 2 个函数。我确信有一种方法可以通过一个函数实现这一点,该函数首先加载标点符号映射,然后组成最终字符串,但老实说,这会很丑陋。
import java.util.*;
import java.util.stream.*;
public class HelloWorld{
static Character[] punctuationCharacters = {',','.','!'};
public static void main(String []args){
System.out.println(reverseSentenceWithPunctuation("Jack, come home!"));
}
private static String reverseSentenceWithPunctuation(String sentence) {
String[] parts = sentence.split(" ");
return generate(0, parts, extractPunctuationMap(0, parts));
}
private static Map<Integer, Character> extractPunctuationMap(int index, String[] parts){
Map<Integer, Character> map = new HashMap<>();
if (index >= parts.length) {
return map;
}
char lastSymbol = parts[index].charAt(parts[index].length() - 1);
if (Arrays.stream(punctuationCharacters).anyMatch(character -> character == lastSymbol)) {
parts[index] = parts[index].substring(0, parts[index].length() - 1);
map = Stream.of(new Object[][] {
{ index, lastSymbol}
}).collect(Collectors.toMap(data -> (Integer) data[0], data -> (Character) data[1]));
}
map.putAll(extractPunctuationMap(index + 1, parts));
return map;
}
private static String generate(int index, String[] parts, Map<Integer, Character> punctuationMap) {
if (index >= parts.length) {
return "";
}
String part = index == 0? " " + parts[index] : parts[index];
if (punctuationMap.containsKey(parts.length -1 - index)) {
part += punctuationMap.get(parts.length -1 - index);
}
return generate(index + 1, parts, punctuationMap) + part;
}
}
在伪代码中可能是这样的:
- 取整句
(一)。得到第一个字
(b)。硬道理
(如果第一个或最后一个单词后有标点符号,请留在那里)
- swap(a, b) and return 剩下的句子中间
- 重复(1)和(2)直到只有两个词或一个
- return 剩下的最后两个(交换的)单词(如果是一个单词,就 return 那个)
要使用递归实现此任务,应准备一个匹配第一个和最后一个单词并后跟一些定界符的模式:
word1 del1 word2 del2 .... wordLast delLast
在匹配输入的情况下,结果计算为:
wordLast del1 REVERT(middle_part) + word1 delLast
实现示例可能如下(单词被认为包含英文字母和撇号'
用于缩写):
static Pattern SENTENCE = Pattern.compile("^([A-Za-z']+)([^A-Za-z]+)?(.*)([^'A-Za-z]+)([A-Za-z']+)([^'A-Za-z]+)?$");
public static String revertSentence(String sentence) {
Matcher m = SENTENCE.matcher(sentence);
if (m.matches()) {
return m.group(5) + (m.group(2) == null ? "" : m.group(2))
+ revertSentence(m.group(3) + m.group(4)) // middle part
+ m.group(1) + (m.group(6) == null ? "" : m.group(6));
}
return sentence;
}
测试:
System.out.println(revertSentence("Jack, come home!"));
System.out.println(revertSentence("Jack, come home please!!"));
System.out.println(revertSentence("Jane cried: Will you come home Jack, please, don't go!"));
输出:
home, come Jack!
please, home come Jack!!
go don't: please Jack home come you, Will, cried Jane!