java中的排列迭代器

2024-01-26

我想要一个类,它接受一个正整数并生成一个迭代器,让我迭代该正整数下的正数列表的所有可能的排列。
例如。模拟器 p = paermulator(3)
p.next() -> [0,1,2]
p.next() -> [0,2,1]
p.next() -> [1,0,2]
p.next() -> [1,2,0]
...
在本例中,有 6 种可能的排列。 我设计了一个类,但它非常慢,我想让迭代更快。 这是我的设计:
(我这样做是为了让这看起来是可能的。)

    package Mathematica.complexity;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.NoSuchElementException;

/**
 * Tthis will be a class that demonstrate what we call: 
 * a factorial complexity algorithm 
 * it's going to print all the possible permutations of some sort of collection 
 * in java. 
 * <br>
 * A recursive data structure that resembles the process of permutating. 
 * @author dashie
 *
 */
public class FactorialComplexity implements Iterator<List<Integer>>
{

 private List<Integer> G_Data; 


    // sub recursive structure of the class. 
    private FactorialComplexity G_next = null; 

    private int G_ChoosenIndex = 0; 

    private boolean G_canProduceNextElement= true;

    public static void main(String[] args) 
    {


    }

    public FactorialComplexity(int NumbersofElements)
    {
        if(NumbersofElements <0)throw new AssertionError();
        this.G_Data = new LinkedList<>();

        for(int i =0; i< NumbersofElements;i++)this.G_Data.add(i);

        this.prepareSubStructure();

    }

    protected FactorialComplexity(List<Integer> argIn)
    {

        this.G_Data = argIn;
        this.prepareSubStructure();

    }


    /**
     * Using the internal index to return the current element it is 
     * pointing at. 
     * <br></b>I doesn't increment the internal pointer. </b>
     * @return
     */
    public Integer getChoosenElement()
    {
        //if(this.G_Data.size() == 0)return null;
        return this.G_Data.get(this.G_ChoosenIndex);
    }

    /**
     * This function serves for the iterator. 
     * @return
     */
    public List<Integer> getPermutation()
    {
        // two of the base case. 
        if(this.G_Data.size()==0)
        {
            return new LinkedList<>();
        }
        if(this.G_Data.size()==1)
        {
            List<Integer> temp = new LinkedList<>();
            temp.add(this.G_Data.get(0));
            return temp;
        }

        return this.getPermutation_part1(new LinkedList<Integer>());
    }

    private List<Integer> getPermutation_part1(List<Integer> argIn)
    {
        argIn.add(getChoosenElement());
        argIn.addAll(this.G_next.getPermutation());
        return argIn;
    }


    /**
     * <ol>
     * <li>If the sub-structure has next element, increment the sub structure.
     * <li>If not, increment the index in this instance and recreate sub structure. 
     * <li>be careful about the base case please. 
     * </ol>
     * 
     * @return 
     * if this, including sub structure should be incremented. 
     * 
     */
    protected boolean increment()
    {

        if(this.G_next!= null)
        {
            boolean temp = this.G_next.increment();
            int pointer = this.G_ChoosenIndex;
            if(this.G_ChoosenIndex+1<this.G_Data.size())
            {
                if(temp)
                {
                    this.G_ChoosenIndex++;
                    this.prepareSubStructure();
                }
                return false;
            }
            else
            {
                return (this.G_ChoosenIndex+1 == this.G_Data.size())&&temp;
            }
        }
        else
        {
            //empty means not choice can make. 
            return true;
        }
    }




    @Override
    /**
     * All the nodes are at its last index. 
     */
    public boolean hasNext()
    {
        if(!this.G_canProduceNextElement)return false;
        if(this.isAllPointingAtLastIndex())this.G_canProduceNextElement=false;
        return true;
    }


    /**
     * This index in this class instance and 
     * all its sub structure are pointing at the last index? 
     * @return
     */
    boolean isAllPointingAtLastIndex()
    {
        if(this.G_Data.size()<=1)
        {
            return true;
        }
        return this.G_ChoosenIndex+1
                ==
               this.G_Data.size()&&this.G_next.isAllPointingAtLastIndex();
    }



    @Override
    public List<Integer> next() 
    {

        List<Integer> result = this.getPermutation();
        this.increment();
        return result;
    }

    public String toString()
    {
        String s = new String();
        s+= this.G_Data+":"+this.G_ChoosenIndex+"->";
        if(this.G_next!= null)s+= this.G_next.toString();
        return s;
    }



    /**
     * <ol>
     * <li>Base case: the list in this instant is empty. 
     * <li>Make a copy of the local collection, excluding the 
     * element the pointer is pointing to
     * <li>Make connect the this object to its sub structure and recurse. 
     * </ol>
     */
    protected void prepareSubStructure()
    {
        if(this.G_Data.size() == 0)return;
        List<Integer> temp = new LinkedList<>();
        temp.addAll(this.G_Data);
        temp.remove(this.G_ChoosenIndex);
        this.G_next = new FactorialComplexity(temp);
        this.G_next.prepareSubStructure();
    }


    public static int factorial(int n)
    {
        if(n<0)return 0;
        if(n<=1)return 1;
        return n*factorial(n-1);
    }

}

总结一下: 该类像链表一样递归,每个节点都包含一个指示其指向的元素的索引,以及从前一个节点传递的所有元素的列表。

这种方法有多天真?我怎样才能让它更快?


这是一个更好的解决方案,灵感来自https://stackoverflow.com/a/10117424/312172 https://stackoverflow.com/a/10117424/312172

为了实现这一目标,我们不是得到一个混乱的元素列表,而是关注从列表中扣除元素时所做的选择。 给函数一个大小,以及一个小于阶乘(大小)的数字;它将返回我们需要做出的一系列选择才能获得排列。

例如:
getTheIndexOfSelection(100,5)-> 对于 5 个元素的列表,我们需要第 100 个排列。

它应该输出:[4,0,2,0,0]

这意味着,删除索引 4 处的元素,对于被删除的列表,删除 0 处的元素 ....

如果列表是[1,2,3,4,5];这将是采购:
[1,2,3,4,5] 删除索引 4 -> 5
[1,2,3,4] 删除索引 0 -> 1
[2,3,4] 删除索引 2 -> 4
[2,3] rovmove 索引 0 -> 2
[3] 删除索引 0 -> 3
我们按顺序删除的所有元素都是排列。

/**
     * Feed this function a number, it gives you a sequence of choices 
     * to make a permutation. 
     * <br>
     * if this return [0,0,0,0]
     * it means remove element at 0, and then remove again... until 
     * reaches the end. 
     * @return
     * 
     * @param
     * len: the length of the list
     * n: the number that got match to a certain permutation. 
     */
    public static int[] getTheIndexOfSelection(int n, int size)
    {
        int[] lst = new int[size];
        return getTheIndexOfSelection( n,  size,  0, lst);

    }




 private static int[] getTheIndexOfSelection(int n, int size, int index, int[] lst)
    {
        if(size==1)
        {
            int[] result = {0}; // a list of one element, you can only choose the one that is in it
            // which is at index 0; 
            return result;
        }

        if(n >= factorial(size))return null; // This is not possible to do. 

        size-=1;
        int   firstchoice = n/factorial(size);

        lst[index]        = firstchoice;

        n = n-firstchoice*factorial(size);

        if(size>1)return getTheIndexOfSelection(n ,size, index+1, lst);
        return lst;
    }

这是一个更好的解决方案,因为:

  1. 速度实际上取决于阶乘函数,假设阶乘非常快,这将是 o(n)。
  2. 它将数字与排列相匹配,从而使映射和迭代器等可扩展。
  3. 这不是完整的解决方案,剩下要解决的部分现在几乎是微不足道的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中的排列迭代器 的相关文章

  • 使用 POST 将数据从 Android 发送到 AppEngine Datastore

    抱歉 如果这是一个简单的问题 但我只是不知道我应该做什么 而且我认为我有点超出了我的深度 我想将数据从 Android 应用程序发送到在 Google App Engine 上运行的应用程序 数据必须从那里写入数据存储区 我的数据主要采用对
  • Grizzly 和 Servlet 容器上下文

    我试图在我编写的 在 Grizzly 上运行的 Servlet 中获取一些注入的上下文 例如 Session 或 HttpServletRequest 但我所做的似乎都不起作用 整个过程似乎过早地停止了 并出现以下错误 SEVERE Mis
  • AbstractCollection 的 toArray 方法的实现中的代码有什么用

    public Object toArray Estimate size of array be prepared to see more or fewer elements Object r new Object size Iterator
  • 检索和设置 IntelliJ IDEA 插件开发的拆分窗口设置

    我正在编写一个 IntelliJ IDEA 插件 用于保存打开选项卡的会话 称为选项卡会话 https github com alp82 idea tabsession 这个问题是后续问题IntelliJ IDEA 插件开发 保存选项卡组
  • Java 多头中的斐波那契计算显示负值

    我的斐波那契计算器工作正常 但当数字增加时 结果会出现负值 就像它是一个Integer超过其最大值 它正在使用缓存java util Map
  • 是否可以使用检测重新定义核心 JDK 类?

    我想重新定义字节码StackOverflowError构造函数 因此当堆栈溢出发生时我有一个 钩子 我想要做的就是在构造函数的开头插入对我选择的静态方法的单个方法调用 是否有可能做到这一点 您应该能够使用两种方法之一来完成此操作 除非在过去
  • 在 Eclipse 中跨文件搜索注释掉的代码

    有没有一种快速方法可以在 Eclipse 中查找 Java 文件中所有注释掉的代码 也许是搜索中的任何选项 或者任何可以执行此操作的附加组件 它应该只能找到被注释掉的代码 而不是普通的注释 在 Eclipse 中 我只是在打开正则表达式复选
  • Android - 内容值覆盖现有行

    我正在尝试使用插入值ContentValues 我已将 5 个值插入到 5 列中 运行应用程序后 我只有最后一组值的行ContentValues 前四组未插入 ContentValues cv new ContentValues cv pu
  • JPA 为每个项目选择最新实例

    假设我有一个会议实体 每次会议都有一个与会者和一个会议日期 在我的会议表中 我可能为每个与会者举行多个会议 每个会议都有不同的日期 我需要一个 JPA 查询 该查询将为所有与会者仅选择最新的会议 例如 如果我的桌子看起来像这样 Meetin
  • UnsupportedOperationException:特权进程中不允许使用 WebView

    我在用android sharedUserId android uid system 在我的清单中获得一些不可避免的权利 从 HDMI 输入读取安卓盒子 http eweat manufacturer globalsources com s
  • AIX:IBM Java:java.net.SocketException:连接超时:可能是由于地址无效

    当尝试与我们的服务器建立 SSL 连接时 我们在 IBM AIX 上经常看到以下异常 java net SocketException Socket closed at com sun net ssl internal ssl SSLSoc
  • 使用java读取Excel工作表的单列

    我有一张 Excel 表格 我想编写一个方法 该方法将参数作为要读取的列号 并返回一个由该列中的所有数据组成的数组 然后将该列元素放置在 xml 工作表中 我怎样才能编写一个方法来做到这一点 使用 Apache POI 您可以在他们的使用页
  • 从 AlertDialog 返回值

    我想构建一个函数来创建 AlertDialog 并返回用户输入的字符串 这是我用于创建对话框的函数 如何返回该值 String m Text private String openDialog String title AlertDialo
  • 将 @RequestLine 与 Feign 一起使用

    我有一个工作 Feign 接口定义为 FeignClient content link service public interface ContentLinkServiceClient RequestMapping method Requ
  • 使用 Mockitos 传递参数化输入

    我正在使用 Mockito 进行单元测试 我想知道是否可以使用 Junit 测试中的方式发送参数化输入参数 e g InjectMocks MockClass mockClass new MockClass Test public void
  • 如何强制初始化 Hibernate JPA 代理以在 JSON 调用中使用它

    我有一个 Spring 3 JPA 2 0 应用程序 在我的 Controller我需要一个初始化的对象 但我有代理 我需要能够以编程方式初始化它 我需要类似的功能org hibernate Hibernate initialize Obj
  • 如何在jpa中共享EntityManagerFactory

    我是 jpa 的新手 这是场景 我正在开发一个 Web 应用程序 其中 多个用户可以登录 当 user1 注销时 我正在使用下面的代码 public static void closeEntityManagerFactory if enti
  • JBoss 5 截断 base64 cookie 字符串的尾部 =

    从 JBoss 4 升级到 JBoss 5 后 我注意到最烦人的回归 它截断 base64 cookie 值的尾部等号 我花了很长时间才明白问题不是我的代码而是 JBoss 的 我用 google 搜索了一下 发现这是一个已知的问题issu
  • 从 AJP 连接器请求中检索 Shibboleth 属性

    当我在 Apache 上运行 Shibboleth 身份验证时遇到了一个奇怪的问题 当 Tomcat7 在后端运行时 Apache 通过 mod proxy ajp 发送所有内容 Shibboleth 的参数也是如此 In the 文档 h
  • 在 Vavr 中结合任一者?

    我有几个Vavr https www vavr io Either https www vavr io vavr docs either的 我想调用一个函数Right每个 Either 的值 例如 Either

随机推荐