Java 如何编写产生格雷码的递归函数
我使用的是格雷码,我得到了几乎所有的东西,但是当代码运行时,比如1位或2位,它只打印0000而不是00 01 11 10Java 如何编写产生格雷码的递归函数,java,recursion,Java,Recursion,我使用的是格雷码,我得到了几乎所有的东西,但是当代码运行时,比如1位或2位,它只打印0000而不是00 01 11 10 class GrayCode { static void genGC(int n){ if(n == 0){ System.out.println(n); } else{ genGC(n-1); genGC(n-1)
class GrayCode {
static void genGC(int n){
if(n == 0){
System.out.println(n);
}
else{
genGC(n-1);
genGC(n-1);
}
}
public static void main(String[] args) {
int a = 2;
genGC(a);
}
}
您的问题是,所需位长的格雷码不仅仅是位长小于1的格雷码的级联 这似乎是可行的-尽管有不必要的列表复制量-我可能会尝试在以后的版本中修复
/**
* Prefix every element of the list with the string.
*
* @param list - The list to prefix.
* @param prefix - The string to prefix each element.
* @return - A new prefixed list.
*/
private List<String> prefix(List<String> list, String prefix) {
List<String> prefixed = new ArrayList<>(list.size());
for (String s : list) {
prefixed.add(prefix + s);
}
return prefixed;
}
/**
* Reflect(reverse) a list.
*
* @param list - The list to reverse.
* @return The reversed list.
*/
private List<String> reflected(List<String> list) {
List<String> reflected = new ArrayList<>(list.size());
// use an ArrayList so I can reverse iterate.
for (ListIterator<String> backwards = new ArrayList<>(list).listIterator(list.size()); backwards.hasPrevious();) {
reflected.add(backwards.previous());
}
return reflected;
}
// Grey codes of one-bit numbers is (0,1).
private static final List<String> OneBit = Arrays.asList("0", "1");
public List<String> greyCodes(int bits) {
if (bits <= 1) {
return OneBit;
} else {
List<String> smaller = greyCodes(bits - 1);
// Prefix the current list with "0"
List<String> grey = prefix(smaller, "0");
// and a reflected version of that list with "1"
grey.addAll(prefix(reflected(smaller), "1"));
return grey;
}
}
/**
*在列表的每个元素前面加上字符串。
*
*@param list-要添加前缀的列表。
*@param prefix-为每个元素添加前缀的字符串。
*@return-一个新的前缀列表。
*/
私有列表前缀(列表、字符串前缀){
列表前缀=新的ArrayList(List.size());
用于(字符串s:列表){
前缀。添加(前缀+s);
}
返回前缀;
}
/**
*反映(颠倒)一个列表。
*
*@param list-要反转的列表。
*@返回反向列表。
*/
反映的私人列表(列表){
List reflected=newarraylist(List.size());
//使用ArrayList,这样我可以反向迭代。
for(ListIterator向后=新建ArrayList(list).ListIterator(list.size());向后.hasPrevious();){
reflected.add(backwards.previous());
}
回报反映;
}
//一位数字的灰色代码为(0,1)。
私有静态最终列表OneBit=Arrays.asList(“0”、“1”);
公共列表灰色代码(整数位){
如果(位生成具有n位的第k个格雷码的实际递归是(“| |”表示串联):
对于k&geq;2n-1,G(n,k)=1 | G(n-1,2n-k-1)
对于kn-1,G(n,k)=0 | G(n-1,k)
使用停止条件G(1,0)=0和G(1,1)=1,并且具有0&leq;k&leq;2k-1
注意(2)中的减法。它对应于最后4位数字序列的前半部分是后半部分的镜像。这就是为什么格雷码有时被称为反射二进制码(RBC)
如果您喜欢Lisp/Scheme/etc,则可以使用以下方法生成带有格雷码的位数组:
(defun gray (n k)
"Returns the kth Gray code of an n-bit sequence. Output is in the form of a bit array."
(assert (< k (expt 2 n)) (n) "k cannot be higher than ~A~%" (1- (expt 2 n)))
(cond
((= n 1)
(if (zerop k) #*0 #*1))
((>= k (expt 2 (1- n)))
(concatenate 'bit-vector #*1 (gray (1- n) (- (expt 2 n) k 1))))
(t
(concatenate 'bit-vector #*0 (gray (1- n) k)))))
(非灰灰色(n k)
“返回n位序列的第k个格雷码。输出为位数组形式。”
(assert(=k(表达式2(1-n)))
(连接“位向量”#*1(灰色(1-n)((表达式2n)k1)))
(t
(连接“位向量#*0(灰色(1-n)k()(#))”))
注意:上面的cond
与Java中的switch/case
类似。上面的函数是上面递归公式的直接实现
如果您不喜欢Lisp,并且递归不是程序的绝对要求,则可以通过实现以下公式来修改代码:
gray=num^(num>>1)
干杯,
Paulo这是一个相当简单的Java递归程序,它接受正整数n并生成n位格雷码:
public static String swap(String s, String r, int i)
{
i = i-1;
String t = s.substring(0,i) + r + s.substring(i+1);
return t;
}
swap
接受一个字符串并将其i-1字符更改为另一个仅包含一个字符的字符串
public static void beckett(int n, String s)
{
if (n == 0) return;
beckett(n-1, s);
System.out.println(swap(s, "1", n)); s = swap(s, "1", n);
beckett(n-1, s);
}
beckett
(参考beckett的一部名为Quad的戏剧)生成灰色代码
public static void grayCodes(int n)
{
String s = "";
for (int i = 0; i < n; i++)
s += "0";
System.out.println(s);
beckett(n, s);
}
对于示例输入3
,它给出以下输出:
000
100
010
110
001
101
011
111
希望这能有所帮助。您只调用System.out.println(n);
如果n为0,您希望得到什么?您到底想要实现什么?
000
100
010
110
001
101
011
111