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,你的任务完成了。