字符串修改异常:A<数字>]替换为A[<数字>]格式错误排查
Problem Statement
I need to transform all occurrences of A<digit(s)>] (where digits range from 0 to Integer.MAX_VALUE) to A[<digit(s)>] in a given string.
Expected Input/Output
- Input:
A5]-A4]-A3]-A2]-A1]-A0]→ Expected Output:A[5]-A[4]-A[3]-A[2]-A[1]-A[0] - Input:
I=A4]-A5]pABSI)<=((A0]-A1])^2+(A2]-A3])^2)^0.5<=I}→ Expected Output:I=A[4]-A[5]pABSI)<=((A[0]-A[1])^2+(A[2]-A[3])^2)^0.5<=I}
Actual (Incorrect) Output
A[5]-A[[4]-A[3]-A[2]-A[1]-A0]I=A[4]-A[5]pABSI)<=((A[0]-A[1])^2+(A[[2]-A3])^2)^0.5<=I}
Current Code
private String finalPrg = ""; private int MAIN_LOOP = 0; private void eval(String s) { while (MAIN_LOOP < s.length()) { // more cases here, irrelevant switch (s.charAt(MAIN_LOOP)) { case ']': evalArrayGetter(finalPrg, MAIN_LOOP); break; default: finalPrg += s.charAt(MAIN_LOOP); break; } MAIN_LOOP++; } } private void evalArrayGetter(String s, int p) { int i; for (i = p-1; i > 0; i--) { if (s.charAt(i)=='A') { break; } } finalPrg =s.substring(0,i+1) + "[" +s.substring(i+1)+"]"; }
Root Cause Analysis
The core issue with the current code is that it uses the original string's index (p) to manipulate the dynamically changing finalPrg string. Since each replacement (A<digit>] → A[<digit>]) increases the length of finalPrg, the original string's indices no longer align with finalPrg's indices. This leads to incorrect positioning of the A character when processing subsequent ] characters, resulting in nested brackets like A[[4].
Additionally, the evalArrayGetter method doesn't verify that the characters between A and ] are actually digits, which could lead to unintended replacements if there are non-digit characters between them.
Solution
Instead of reacting to ] characters and backtracking with misaligned indices, we can proactively detect A characters, collect the following digits, and check if the next character is ] to perform the correct replacement. This approach avoids index mismatches and ensures we only target valid A<digit(s)>] patterns.
Fixed Code
private String finalPrg = ""; private int MAIN_LOOP = 0; private void eval(String s) { while (MAIN_LOOP < s.length()) { char currentChar = s.charAt(MAIN_LOOP); if (currentChar == 'A') { // Start building the transformed segment finalPrg += 'A'; MAIN_LOOP++; // Collect all consecutive digits after 'A' StringBuilder digits = new StringBuilder(); while (MAIN_LOOP < s.length() && Character.isDigit(s.charAt(MAIN_LOOP))) { digits.append(s.charAt(MAIN_LOOP)); MAIN_LOOP++; } // Check if the next character is ']' to perform replacement if (MAIN_LOOP < s.length() && s.charAt(MAIN_LOOP) == ']') { finalPrg += "[" + digits + "]"; MAIN_LOOP++; // Skip the ']' since we've handled it } else { // If no closing ']', append the digits as-is finalPrg += digits; // Don't increment MAIN_LOOP here—we need to process the non-digit character next } } else { // Handle all other characters normally finalPrg += currentChar; MAIN_LOOP++; } } }
Explanation
- Proactive
ADetection: When we encounter anA, we immediately start collecting any following digits. - Digit Collection: We use a
StringBuilderto gather all consecutive digits afterA, ensuring we capture multi-digit numbers (likeA123]→A[123]). - Validate Closing
]: After collecting digits, we check if the next character is]. If yes, we wrap the digits in[]and append tofinalPrg. If not, we append the digits normally and continue processing. - Index Alignment: By incrementing
MAIN_LOOPonly as we process each character (or segment), we ensure our index always aligns with the current position in the original string, avoiding mismatches with the growingfinalPrg.
This approach will correctly transform all valid A<digit(s)>] patterns to A[<digit(s)>] without producing nested brackets or missing replacements.
内容的提问来源于stack exchange,提问作者mindoverflow

