【问题标题】:How to get all one and two letter combinations in order from a word?如何从一个单词中按顺序获得所有一个和两个字母组合?
【发布时间】:2021-07-19 16:43:37
【问题描述】:

比如有一行

String str = "program";

需要得到所有可能的组合,如:

  • p-r-o-g-r-a-m
  • p-r-o-g-r-am
  • p-r-o-g-ra-m
  • pro-og-r-am

等等。

我如何在 Java 中做到这一点?或者至少告诉我一个通用算法(举例)?

打破最后期限不是问题,一次至少一个字符,至少两个,例如

for (int i = 0; i <str.length () - 1; i = i +2) {
             String strTemp = str.charAt (i) + "" + str.charAt (i + 1);
               System.out.println (strTemp);
}

但是如何获取(绕过)1和2的所有可能组合,目前还不清楚如何编程。

【问题讨论】:

  • 抛出一些想法:每个字母都有“配对”或“未配对”的状态。更进一步,我们有一个布尔值 1/0 表示每个字母的“配对”。接下来想象一个计数器,它从全 0(每个字母 0)一直到全 1(每个字母 1)。
  • 我不会像@LukeBriggs 建议的那样考虑配对的字母,而是处理字母之间的间隙。它们可以配对或不配对。两个相邻的间隙可能不会同时配对。递归方法可能是枚举所有可能性的最简单方法。
  • 是的,“dash”与“no dash”是一个更简单的概念。重新阅读问题,实际上似乎没有必要将他们限制在两人中。也就是说,progr-am 似乎也是有效的,因此它可以只是一个代表破折号状态的直接计数器。
  • 不,“progr-am”无效。每个部分正好 1 或 2 个字母

标签: java algorithm


【解决方案1】:

您可以使用递归编程来做到这一点:

public Set<String> combination(String str){
    final Set<String> results = new HashSet<>();
    if(str.length() == 0)
        return results;
    if(str.length() == 1){
        results.add(str);
        return results;
    }
    if(str.length() == 2){
        results.add(str.charAt(0) + "-" + str.charAt(1));
        results.add(str);
        return results;
    }
    String head = str.substring(0, 1);
    final Set<String> remaining = combination(str.substring(1));
    remaining.forEach(s -> {
        int i = s.indexOf("-");
        if(i == 1){
            results.add(head + s);
            results.add(head + "-" + s);
        } else if(s.length() == 2){
            results.add(head + "-" + s);
        } else if(i == 2){
            results.add(head + "-" + s);
        }
    });
    return results;
}

【讨论】:

    【解决方案2】:

    我的建议:

    将单个字母编码为0,将一对字母编码为1。现在所有的分解都映射到二进制数。枚举所有自然数,从 0 开始,直到 2^(L-2) 一个长度为 L 的单词,跳过数字,如 2O+Z&gt;LOZ 零)。

    例如

    p-r-o-g-r-a-m: 0000000
    p-r-o-g-r-am:   000001
    p-r-o-g-ra-m:   000010
    p-r-o-gr-am:     00011
         ....
    pr-o-g-r-a-m:   100000
    

    我不确定这是否有效,但目前我认为没有比尝试所有自然项并跳过不兼容的项更好的枚举方式。


    更新:

    检查这个:What is the best way to loop through integers with at most k bits ON?

    【讨论】:

      【解决方案3】:

      我喜欢 hatef Alipoor 的递归方法。但我会把它放在更小的方法中以使其更具可读性。

      这是我的代码:

      public class WordCombiner {
      
        public static void main(String[] args) {
          new WordCombiner("program").run();
        }
        
        private final String word;
        
        public WordCombiner(String word) {
          this.word = word;
        }
        
        public void run() {
          resolveCobination("", 0);
        }
        
        private void resolveCobination(String builder, int currentIndex) {
          appendSingleCharacter(builder, currentIndex);
          if (currentIndex+1 < word.length()) {
            appendDoubleCharacter(builder, currentIndex);
          }
        }
      
        private void appendSingleCharacter(String builder, int currentIndex) {
          builder = builder + word.charAt(currentIndex++);
          resolveOrPrint(builder, currentIndex);
        }
      
        private void appendDoubleCharacter(String builder, int currentIndex) {
          builder = builder + word.charAt(currentIndex++);
          builder = builder + word.charAt(currentIndex++);
          resolveOrPrint(builder, currentIndex);
        }
      
        private void resolveOrPrint(String builder, int currentIndex) {
          if (currentIndex < word.length()) {
            builder = builder + "-";
            resolveCobination(builder, currentIndex);
          } else {
            System.out.println(builder);
          }
        }
        
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-26
        • 1970-01-01
        • 2016-11-25
        相关资源
        最近更新 更多