Java 按特定顺序计算0和1序列的算法

Java 按特定顺序计算0和1序列的算法,java,recursion,Java,Recursion,我正在尝试编写一个算法next(),用以下顺序规则计算下一个序列: 所有序列的长度均为n,由0s和1s组成 1s较少的序列将在1s较多的序列之前 在具有相同数量1s的序列中,左侧1s较多的序列将位于左侧1s较少的序列之前(即,如果从左到右逐个元素进行比较,则第一个具有1的序列,其中另一个具有0的序列将位于第一位) 调用next()15次时,n=4的输出将是: 0000 1000 0100 0010 0001 1100 1010 1001 0110 0101 0011 1110 1101 1011

我正在尝试编写一个算法
next()
,用以下顺序规则计算下一个序列:

  • 所有序列的长度均为
    n
    ,由
    0
    s和
    1
    s组成

  • 1
    s较少的序列将在
    1
    s较多的序列之前

  • 在具有相同数量
    1
    s的序列中,左侧
    1
    s较多的序列将位于左侧
    1
    s较少的序列之前(即,如果从左到右逐个元素进行比较,则第一个具有
    1
    的序列,其中另一个具有
    0
    的序列将位于第一位)

  • 调用
    next()
    15次时,
    n=4
    的输出将是:

    0000
    1000
    0100
    0010
    0001
    1100
    1010
    1001
    0110
    0101
    0011
    1110
    1101
    1011
    0111
    1111
    
    每次调用
    next()
    都应该更新一个静态变量以保存最后的结果。第一个
    0
    s序列将预先生成,并应固定长度

    我正试图用Java实现这一点,所以我更愿意用Java找到一个,尽管这并不重要,因为主要的问题是逻辑

    我的主要想法是移动最右边的
    1
    ,但主要问题是如何处理在最右边位置有
    1
    的情况,我不太清楚如何从这些情况继续

    这是我的尝试,但它可能有一些缺陷,我不知道如何调试。此外,我认为这可以比我在这里做的更好:

    public static int[] next() {
        int i = last_res.length - 1;
        while (i >= 0) {
            if (last_res[i] == 1) {
                last_res[i] = 0;
                if (i + 1 < last_res.length) {
                    last_res[i + 1] = 1;
                    return last_res;
                } else {
                    i--;
                    while (i >= 0) {
                        if (last_res[i] == 1) {
                            last_res[i + 1] = 1;
                            return last_res;
                        }
                        i--;
                    }
                }
            }
            i--;
        }
        last_res[0] = 1;
        return last_res;
    }
    
    publicstatic int[]next(){
    int i=最后一个分辨率长度-1;
    而(i>=0){
    if(last_res[i]==1){
    last_res[i]=0;
    如果(i+1<最后的分辨率长度){
    last_res[i+1]=1;
    返回最后一个_res;
    }否则{
    我--;
    而(i>=0){
    if(last_res[i]==1){
    last_res[i+1]=1;
    返回最后一个_res;
    }
    我--;
    }
    }
    }
    我--;
    }
    last_res[0]=1;
    返回最后一个_res;
    }
    

    谢谢

    这将解决您的问题-但其中没有递归:-)

    另外,当前值没有静态变量-相反,我将传递当前值以计算下一个。。。但也许这能帮你完成任务

        public static void main(String... args) {
            int n = 10;         
            //if n was dynamic, you'd compute that to have exact number.
            String current = leastSignificantForN(n, 0); 
            while(countOnes(current) < n) {
                System.out.println(current);
                current = next(current);
            }
            System.out.println(current);
        }
    
        private static String next(String current) {
            long co = countOnes(current);
            if(isMostSingificantForN(current, co)) {
                return leastSignificantForN(current.length(), co+1);
            } else {
                return increaseSignificance(current);
            }
        }
    
        private static String increaseSignificance(String current) {
            //Look for "moveable" 1
            int idx = current.lastIndexOf("01");
            StringBuilder sb = new StringBuilder();
            //Kepp string to the left intact
            for(int i = 0; i < idx; ++i) {
                sb.append(current.charAt(i));
            }
            sb.append("10");
            for(int i = idx + 2; i < current.length(); ++i) {
                sb.append(current.charAt(i));
            }
            return sb.toString();
        }
    
        private static String leastSignificantForN(int targetLength, long length) {
            StringBuilder sb = new StringBuilder();
            for(int i = 0; i < targetLength - length; ++i) {
                sb.append('0');
            }
            for(int i = 0; i < length; ++i) {
                sb.append('1');
            }
            return sb.toString();
        }
    
        private static boolean isMostSingificantForN(String current, long co) {
            int pos = 0;
            int count = 0;
            while(pos < current.length() && current.charAt(pos++) == '1') {
                ++count;
            }
            return count == co;
        }
    
        private static long countOnes(String current) {
            return current.chars().filter(i -> '1' == i).count();
        }
    
    publicstaticvoidmain(字符串…参数){
    int n=10;
    //如果n是动态的,你会计算出精确的数字。
    串电流=最小有效值n(n,0);
    while(countone(当前)'1'==i.count();
    }
    
    这是一个非常干净的解决方案,但您将预先计算所有值,因此如果性能有问题,则应考虑其他方法

        public static void main(String[] args) {
            final int size = 4;
            List<String> results = new ArrayList<>();
            for (int i = 0; i <= size; i++) {
                calculateChances(size - i, i, "", results);
            }
            results.stream().forEach(System.out::println);
        }
    
        public static void calculateChances(int zeroes, int ones, String current, List<String> results) {
            if (zeroes == 0 && ones == 0) {
                results.add(current);
                return;
            }
            if (ones > 0) {
                calculateChances(zeroes, ones - 1, current + "1", results);         
            }
            if (zeroes > 0) {
                calculateChances(zeroes - 1, ones, current + "0", results);         
            }       
        }
    
    publicstaticvoidmain(字符串[]args){
    最终整数大小=4;
    列表结果=新建ArrayList();
    对于(int i=0;i 0){
    计算值(0,1-1,电流+“1”,结果);
    }
    如果(零>0){
    计算值(0-1,1,电流+“0”,结果);
    }       
    }
    

    如果你想要一个简单的next实现,你可以从结果列表中创建一个迭代器。

    你能展示你到目前为止做了什么吗?你的输出不应该是
    n
    4
    吗?所以对于现有的最后一个输入,有三个选项:1)有一个“更重要”的解决方案,具有相同的1。2) 你需要更多的1s,从最不重要的1s开始,或者3)你的结果是所有1s,你的任务完成了。