我正在使用格雷码,我几乎得到了所有东西,但是当代码运行时,如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);
}
}
public static void main(String[] args) {
int a = 2;
genGC(a);
}
}
答案 0 :(得分:0)
你的问题是所需位长的格雷码不仅仅是比特长度格雷码的串联。 It's more complicated than that
这似乎有效 - 尽管有不必要的列表复制量 - 我可能会尝试在以后的版本中修复它。
/**
* 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;
}
}
答案 1 :(得分:0)
生成具有n位的k th 格雷码的实际递归是(&#39; ||&#39;表示连接):
使用停止条件G(1,0)= 0且G(1,1)= 1且0≤k≤2 k - 1
注意(2)中的减法。它对应于最后4位数的序列的前半部分是后半部分的镜像的事实。这就是为什么格雷码有时被称为反射二进制码(RBC)。
如果是Lisp / Scheme /等。是你的事,你可以使用:
生成格雷码的位数组(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)))))
NB。上面的cond
与Java中的switch/case
类似。上面的函数是上面递归公式的直接实现。
如果Lisp不是你的事情,如果递归不是你的程序的绝对要求,你可以通过实现公式来修改你的代码:
gray = num ^ (num >> 1)
干杯, 圣保罗
答案 2 :(得分:0)
这是一个相当简单的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
(参考贝克特的一部名为《 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);
}
grayCodes
使beckett
的使用更加容易(仅减少了输入数量)。
您可以使用以下方法测试以上方法:
public static void main(String[] args)
{
int n = Integer.parseInt(args[0]);
grayCodes(n);
}
对于示例输入3
,它提供以下输出:
000
100
010
110
001
101
011
111
希望这会有所帮助。