巴西ICPC题:Z数组与前缀数组互转代码报错求助(RTE+WA)
Z函数与KMP前缀函数双向转换的代码问题排查
我正在解决巴西ICPC的一道题目,要求实现Z数组(Z函数)与前缀数组(KMP前缀函数)的双向转换。目前代码存在运行时错误(RTE)和一组测试用例答案错误(WA),但无法定位问题所在(Z函数和KMP函数的基础实现是正确的,未在代码中展示)。
完整任务描述
输入要求
- 第一行输入测试用例数
t,范围为1≤t≤100000 - 每个测试用例包含两行:
- 第一行是字符串长度
n,范围为2≤n≤1000000 - 第二行输入
n-1个0到n-1的整数,对应字符串从第2到第n位的函数值(索引从1开始)
- 第一行是字符串长度
- 所有测试用例的字符串长度总和不超过
1000000
输出要求
对每个测试用例输出两行:
- 假设输入是Z函数值,输出从第2到第n位的前缀函数值;若不存在对应字符串,输出
-1 - 假设输入是前缀函数值,输出从第2到第n位的Z函数值;若不存在对应字符串,输出
-1
- 若结果不唯一,输出任意可行解即可
现有Java主函数代码
public static void main(String[] args) throws IOException { StringBuilder answer = new StringBuilder(); BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); int t = Integer.parseInt(reader.readLine()); for (int i = 1; i <= t; i++) { ArrayList<Integer> input = new ArrayList<>(); int n = Integer.parseInt(reader.readLine().trim()); //added trim() StringBuilder line = new StringBuilder("a"); StringBuilder prefixLine = new StringBuilder("a"); int el; boolean zFunctionExist = true; boolean KMPExist = true; String[] inputChar = reader.readLine().trim().split(" "); //added trim() for (int j = 2; j <= n; j++) { el = Integer.parseInt(inputChar[j - 2].trim()); //added trim() input.add(el); if (line.length() <= n) { if (line.length() > j - 1) { if (el != 0) { if (j - 1 + el <= line.length() - 1) continue; String sub = line.substring(line.length() - j + 1, el); line.append(sub); } } else { if (el == 0) { line.append((char) (j + 'a' - 1)); } else { if (el > line.length()) { String addLine = String.valueOf(line); int count = addLine.length(); while (count <= el) { line.append(addLine); count *= 2; } } else { line.append(line.substring(0, el)); } } } } } ArrayList<Integer> input2 = new ArrayList<>(input); input2.add(0, 0); for (int ind = 0; ind < input2.size(); ind++) { if (input2.get(ind) + ind > input2.size()) zFunctionExist = false; if (input2.get(ind) > ind) KMPExist = false; } if (!zFunctionExist && !KMPExist) { answer.append("-1").append("\n"); answer.append("-1").append("\n"); break; } int[] array = zFunction(String.valueOf(line)); int[] preArray; for (int l = 0; l < input.size(); l++) { if (array[l] != input.get(l)) { zFunctionExist = false; break; } } if (!zFunctionExist) { int element = 0; for (int k = 2; k <= n; k++) { element = input.get(k - 2); if (element == 0) { prefixLine.append((char) (k + 'a' - 1)); } else { prefixLine.append(prefixLine.charAt(element - 1)); } } line = prefixLine; array = zFunction(String.valueOf(line)); preArray = KMP(String.valueOf(line)); for (int l = 0; l < input.size(); l++) { if (input.get(l) != preArray[l]) { KMPExist = false; break; } } } else { preArray = KMP(String.valueOf(line)); for (int l = 0; l < input.size(); l++) { if (input.get(l) != preArray[l]) { KMPExist = false; break; } } } if (zFunctionExist) Arrays.stream(preArray).forEach(e -> answer.append(e).append(" ")); else answer.append("-1"); answer.append("\n"); if (KMPExist) Arrays.stream(array).forEach(e -> answer.append(e).append(" ")); else answer.append("-1"); answer.append("\n"); } System.out.println(answer); }
我尝试寻找能触发错误的反例但无果,希望有人帮忙排查代码中的转换逻辑问题。
内容的提问来源于stack exchange,提问作者Nikifor Telpuk
相关产品推荐
相关产品推荐

