You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

多字符替换的字符串组合生成:含yield的C#代码转Java实现

嘿,我完全懂你的困扰!C#里的yield关键字确实让生成这种字符替换组合的代码变得特别简洁,但Java偏偏没有这个语法糖。不过别担心,我们可以用递归或者自定义迭代器的方式,完美复刻原C#代码的功能,甚至还能实现类似的延迟加载效果呢!

解决方案

1. 一次性生成所有组合(简单直观版)

这种方式适合车牌长度不长、组合数量不多的场景,直接把所有可能的组合收集到List里,逻辑和原C#递归+yield的思路一致,只是用回溯递归来实现。

首先定义替换规则,然后编写递归方法:

import java.util.*;

public class PlateCombinationGenerator {
    // 定义替换规则:key是原字符,value是所有可替换的字符(包括自身)
    private static final Map<Character, List<Character>> REPLACEMENT_RULES = new HashMap<>();
    static {
        REPLACEMENT_RULES.put('1', Arrays.asList('1', 'I'));
        REPLACEMENT_RULES.put('0', Arrays.asList('0', 'O'));
        REPLACEMENT_RULES.put('2', Arrays.asList('2', 'Z'));
        // 可以根据需求添加更多替换规则
    }

    // 对外暴露的生成方法
    public static List<String> generatePlateCombinations(String originalPlate) {
        List<String> combinations = new ArrayList<>();
        generateCombinationsRecursive(originalPlate, 0, new StringBuilder(), combinations);
        return combinations;
    }

    // 递归回溯生成组合
    private static void generateCombinationsRecursive(String plate, int currentIndex, StringBuilder currentCombination, List<String> result) {
        // 递归终止条件:处理完所有字符,把当前组合加入结果
        if (currentIndex == plate.length()) {
            result.add(currentCombination.toString());
            return;
        }

        char currentChar = plate.charAt(currentIndex);
        // 获取当前字符的所有可能选项:有替换规则就用规则,没有就用自身
        List<Character> possibleChars = REPLACEMENT_RULES.getOrDefault(currentChar, Collections.singletonList(currentChar));

        // 遍历所有可能的替换字符,递归处理下一个位置
        for (char replacement : possibleChars) {
            currentCombination.append(replacement);
            generateCombinationsRecursive(plate, currentIndex + 1, currentCombination, result);
            currentCombination.deleteCharAt(currentCombination.length() - 1); // 回溯,移除当前添加的字符
        }
    }

    // 使用示例
    public static void main(String[] args) {
        String plate = "ABC123";
        List<String> allCombos = generatePlateCombinations(plate);
        for (String combo : allCombos) {
            System.out.println(combo);
        }
    }
}

2. 懒加载版本(类似C# IEnumerable的延迟执行)

如果车牌组合数量很大,一次性生成会占用过多内存,我们可以自定义Iterator来实现类似yield的延迟加载效果——每次调用next()才生成下一个组合,避免一次性加载所有数据。

import java.util.*;

public class LazyPlateCombinationGenerator {
    private static final Map<Character, List<Character>> REPLACEMENT_RULES = new HashMap<>();
    static {
        REPLACEMENT_RULES.put('1', Arrays.asList('1', 'I'));
        REPLACEMENT_RULES.put('0', Arrays.asList('0', 'O'));
        // 添加其他规则
    }

    public static Iterable<String> generatePlateCombinationsLazy(String originalPlate) {
        return () -> new Iterator<String>() {
            // 用栈模拟递归调用栈,每个元素是[当前索引, 当前组合的StringBuilder]
            private final Deque<Object[]> callStack = new ArrayDeque<>();
            private String nextCombination;

            // 初始化栈,准备第一个组合的生成
            {
                callStack.push(new Object[]{0, new StringBuilder()});
                advanceToNextCombination();
            }

            // 预取下一个组合
            private void advanceToNextCombination() {
                nextCombination = null;
                while (!callStack.isEmpty()) {
                    Object[] frame = callStack.pop();
                    int index = (int) frame[0];
                    StringBuilder current = (StringBuilder) frame[1];

                    if (index == originalPlate.length()) {
                        nextCombination = current.toString();
                        return;
                    }

                    char currentChar = originalPlate.charAt(index);
                    List<Character> possibleChars = REPLACEMENT_RULES.getOrDefault(currentChar, Collections.singletonList(currentChar));

                    // 反向入栈,保证组合顺序和递归版本一致
                    for (int i = possibleChars.size() - 1; i >= 0; i--) {
                        char replacement = possibleChars.get(i);
                        StringBuilder newCurrent = new StringBuilder(current);
                        newCurrent.append(replacement);
                        callStack.push(new Object[]{index + 1, newCurrent});
                    }
                }
            }

            @Override
            public boolean hasNext() {
                return nextCombination != null;
            }

            @Override
            public String next() {
                if (!hasNext()) {
                    throw new NoSuchElementException();
                }
                String result = nextCombination;
                advanceToNextCombination();
                return result;
            }
        };
    }

    // 使用示例
    public static void main(String[] args) {
        String plate = "ABC123";
        Iterable<String> lazyCombos = generatePlateCombinationsLazy(plate);
        for (String combo : lazyCombos) {
            System.out.println(combo);
        }
    }
}

这两种方式都能实现原C#代码的功能,你可以根据实际场景选择合适的版本。

内容的提问来源于stack exchange,提问作者RobbiewOnline

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:25:33