Java实现Pig Latin转换时如何保留单词首尾标点符号
Pig Latin 首尾标点保留实现方案
核心逻辑非常简单:将原字符串拆分为前导标点段、中间有效单词段(含中间标点)、后缀标点段三部分,仅对中间段执行原有Pig Latin转换,最后按「前导标点 + 转换后中间段 + 后缀标点」拼接即可。
方案1:递归实现(优先推荐)
你原有标点提取代码的问题是没有区分首尾位置,会把所有标点都存入前导变量,用两个简单的递归函数即可完成首尾标点的拆分:
import java.util.regex.*; public class PigLatinTranslator { public static final String punct = ",./;:'\"?<>[]{}|`~!@#$%^&*()"; // 递归提取前导标点 private static String getStartPunct(String str) { // 空字符串或第一个字符不是标点,结束递归 if (str.isEmpty() || punct.indexOf(str.charAt(0)) < 0) { return ""; } // 是标点就拼接后续递归结果 return str.charAt(0) + getStartPunct(str.substring(1)); } // 递归提取后缀标点 private static String getEndPunct(String str) { // 空字符串或最后一个字符不是标点,结束递归 if (str.isEmpty() || punct.indexOf(str.charAt(str.length() - 1)) < 0) { return ""; } // 是标点就拼接前面的递归结果 return getEndPunct(str.substring(0, str.length() - 1)) + str.charAt(str.length() - 1); } // 你原有Pig Latin转换逻辑,示例中补充了找元音下标的通用逻辑,可替换为你自己的实现 private static String translateMiddle(String middle) { int i = 0; String vowels = "aeiouAEIOU"; while (i < middle.length() && vowels.indexOf(middle.charAt(i)) < 0) { i++; } // 保留你原来的转换代码 return middle.substring(i) + middle.substring(0, i) + "ay"; } // 完整转换方法 public static String translate(String s) { String startPunct = getStartPunct(s); // 去掉前导标点后的剩余字符串 String contentWithoutStart = s.substring(startPunct.length()); String endPunct = getEndPunct(contentWithoutStart); // 提取中间有效单词段 String middle = contentWithoutStart.substring(0, contentWithoutStart.length() - endPunct.length()); // 转换后拼接 return startPunct + translateMiddle(middle) + endPunct; } public static void main(String[] args) { // 测试结果完全匹配要求示例 System.out.println(translate("what?")); // 输出 atwhay? System.out.println(translate("Oh!!!")); // 输出 Ohway!!! System.out.println(translate("\"hello\"")); // 输出 "ellohay" System.out.println(translate("don't")); // 输出 on'tday System.out.println(translate("\"pell-mell\"")); // 输出 "ell-mellpay" } }
方案2:正则实现
用正则分组可以一次性完成三段拆分,代码更简洁:
public static String translateWithRegex(String s) { // 把标点常量转义后拼接为正则字符类 String punctClass = "[" + Pattern.quote(punct) + "]*"; // 三个分组分别匹配前导标点、中间内容、后缀标点 Pattern pattern = Pattern.compile("^(" + punctClass + ")(.*?)(" + punctClass + ")$"); Matcher matcher = pattern.matcher(s); if (matcher.matches()) { String startPunct = matcher.group(1); String middle = matcher.group(2); String endPunct = matcher.group(3); return startPunct + translateMiddle(middle) + endPunct; } return s; }
两种方案都完全兼容你已有的Pig Latin核心转换逻辑,不需要修改原有转换代码即可实现标点保留需求。
内容的提问来源于stack exchange,提问作者StealthWar
相关产品推荐
相关产品推荐

