【问题标题】:Dynamically create loops to iterate over a List of List<String>'s动态创建循环以遍历 List<String> 的列表
【发布时间】:2011-12-03 14:57:29
【问题描述】:

我有一个List&lt;String&gt; 中的List,这是我从外部 API 方法调用中获得的:

List<List<String>> outerList

我必须按照它们在外部列表中的相同顺序连接每个列表中的字符串来创建唯一的组合键。

示例:如果外部列表有 2 个内部列表,例如 list1:{"A","B"} 和 list2:{"C","D"}。那么可能的唯一组合将是 AC、AD、BC 和 BD。

但问题是outerList 的大小是动态的,它可以包含任意数量的内部列表。如果内部列表编号是固定的,那么我可以编写 for 循环并创建组合。

我正在考虑使用反射、递归等的方向,但到目前为止还没有解决它。

public static void main(String[] args) {

    List<List<String>> outerList = new ArrayList<List<String>>();
    List<String> list1 = new ArrayList<String>();
    list1.add("A");
    list1.add("B");
    List<String> list2 = new ArrayList<String>();

    list2.add("C");
    list2.add("D");
    outerList.add(list1);

    outerList.add(list2);

    for(String s1: list1) {
        for(String s2: list2) {
            System.out.println(s1+s2);
        }
    }
}

这里 outerList 有 2 个内部列表,所以我创建了 2 个 for 循环来显式地迭代和连接。但是实时的outerList可以有任意数量的inner list,如何动态循环遍历所有inner loop并拼接?

【问题讨论】:

  • 无需反思。只需使用 for 循环。
  • 也许发布你到目前为止的代码?将帮助人们准确了解您要做什么。
  • 是作业吗?如果是,将其标记为作业。三个列表会发生什么?你必须为每个列表选择一个元素吗? {A,B}{C,D}{E,F} 组合都是 3 个字符长还是也可以是 1 个字符、2 个字符等等?它们是无序的吗? AC = CA?
  • @Daniel Earwicker 我已经用示例代码更新了问题陈述。
  • @stivlo 这不是家庭作业。我当前的客户项目需要该逻辑。是的,每个列表中的一个元素按 3 个列表组合的列表顺序将是 ACE、ACF、ADE、ADF、BCE、BDF、BDE、BDF

标签: java list loops recursion for-loop


【解决方案1】:

具有足够变化的样本数据来证明问题:

    List<List<String>> outerList = new ArrayList<List<String>>();

    List<String> innerList1 = new ArrayList<String>();
    innerList1.add("A");
    innerList1.add("B");
    outerList.add(innerList1);

    List<String> innerList2 = new ArrayList<String>();
    innerList2.add("X");
    innerList2.add("Y");
    innerList2.add("Z");
    outerList.add(innerList2);

    List<String> innerList3 = new ArrayList<String>();
    innerList3.add("P");
    innerList3.add("Q");
    innerList3.add("R");
    outerList.add(innerList3);

保留一个计数器数组:

    int[] positions = new int[outerList.size()];

    boolean another = true;
    while (another) {
        for (int n = 0; n < outerList.size(); n++) {
            System.out.print(outerList.get(n).get(positions[n]));
        }
        System.out.println();

        another = false;
        for (int c = 0; c < outerList.size(); c++) {
            positions[c]++;
            if (positions[c] < outerList.get(c).size()) {
                another = true;
                break;
            }
            positions[c] = 0;
        }
    }

每次在主循环中,我都会从每个内部列表中打印一项。然后我推进柜台,从第一个开始。如果这没有超出第一个内部列表的末尾,我们就可以再次打印了。但如果是这样,我将该计数器设置为零并尝试推进第二个,依此类推。如果它们都归零,就该退出了。

这真的就像计数一样,只是每列都有不同的“基数”(而不是全部以十或二为基数或其他)。

【讨论】:

    【解决方案2】:

    此代码适用于我:

    public class Test
    {  
    
        public static void generate(LinkedList<LinkedList<String>> outerList, String outPut) {
            LinkedList<String> list = outerList.get(0);
    
            for(String str : list) {
                LinkedList<LinkedList<String>> newOuter = new LinkedList<LinkedList<String>>(outerList);
                newOuter.remove(list);
    
                if(outerList.size() > 1) {
                    generate(newOuter, outPut+str);
                 } else {
                   System.out.println(outPut+str);
                 }
            }
        }
    
        public static void main(String[] args) 
        {
            LinkedList<LinkedList<String>> outerList = new LinkedList<LinkedList<String>>();
    
            LinkedList<String> list1 = new LinkedList<String>();
            LinkedList<String> list2 = new LinkedList<String>();
    
            list1.add("A");
            list1.add("B");
    
            list2.add("C");
            list2.add("D");
    
            outerList.add(list1);
            outerList.add(list2);
    
            Test.generate(outerList, "");
        }      
    }
    

    输出:

    交流
    广告
    卑诗省
    BD

    【讨论】:

      猜你喜欢
      • 2019-06-12
      • 2021-03-31
      • 2012-06-16
      • 2020-03-30
      • 2019-01-28
      • 2021-03-06
      • 2021-12-16
      • 2011-03-06
      • 2017-04-30
      相关资源
      最近更新 更多