简体   繁体   中英

grey codes using 2d arrays (C)

My assignment is to print out grey codes using recursion. A user puts in a bit value between 0-8 , therefore the maximum amount of strings you can have is 256 (2^8).

I've got the base case done but i don't know what I would do for the else portion.

My code so far:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>

void gcodes (int n) {
    char bits[256][8];
    int i, j;
    int x = pow (2, n);

    if (n == 1) {
        bits[0][0] = '0';
        bits[1][0] = '1';
    } else {
        gcodes (n-1);
    }

    for (i=0; i<x; i++) {
        for (j=0; j<n; j++) {
            printf("%c", reverse[i][j]);
        }
    printf("\n");
    }
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Invalid number of arguments\n");
        return 0;
    }

    int n;
    n = atoi (argv[1]);

    if (n > 8 || n <= 0) {
        printf("Invalid integer\n");
        return 0;
    }

    gcodes (n);
}

a gray code can have only one bit change from one number to the next consecutive number. and over the whole sequence, there are no repeated values.

Given that criteria, there are several possible gray code implementations.

There are several deadend sequences where the values start off ok, then fail,

Calculating a gray code via code will take lots of experimentation.

In reality it is much easier to simply find a valid gray code sequence from the net, and paste that into any program that needs a gray code sequence.

Most often, a input is a gray coded wheel that is read to determine if the wheel moved rather than something generated in code.

however, if I were implementing a gray code generator, I would expect it to perform exclusive-or between the last generated value and the proposed new/next value and if that is valid (only one bit changed) I would search through the existing table of values to assure it is not a duplicate.

this SO question suggests a possible algorithm:

Non-recursive Grey code algorithm understanding

and the answer is repeated below:

The answer to all four your questions is that this algorithm does not start with lower values of n. All strings it generates have the same length, and the i-th (for i = 1, ..., 2n-1) string is generated from the (i-1)-th one.

Here is the first few steps for n = 4:

Start with G0 = 0000

To generate G1, flip 0-th bit in G0, as 0 is the position of the least significant 1 in the binary representation of 1 = 0001b. G1 = 0001.

To generate G2, flip 1-st bit in G1, as 1 is the position of the least significant 1 in the binary representation of 2 = 0010b. G2 = 0011.

To generate G3, flip 0-th bit in G2, as 0 is the position of the least significant 1 in the binary representation of 3 = 0011b. G3 = 0010.

To generate G4, flip 2-nd bit in G3, as 2 is the position of the least significant 1 in the binary representation of 4 = 0100b. G4 = 0110.

To generate G5, flip 0-th bit in G4, as 0 is the position of the least significant 1 in the binary representation of 5 = 0101b. G5 = 0111.

Since you define

    char bits[256][8];

with automatic storage duration inside the function gcodes() , the array's lifetime ends when returning from the function, so you lose the results of the recursive calls. Thus, at least define it

    static char bits[256][8];

or globally if you want to keep the resulting bits for use outside of gcodes() .


Since in the standard Gray code the least significant bit (bit 0) follows the repetitive pattern of 0110, it is convenient to set the complete pattern in the base case even if it is not needed for n = 1 .

For the i th code's bit j where j > 0 , its value can be taken from bit j-1 of code i/2 .

This leads to the completed function:

void gcodes(int n)
{
    static char bits[256][8];
    int i, j, x = pow(2, n);

    if (n == 1)
    {
        bits[0][0] = '0';
        bits[1][0] = '1';
        bits[2][0] = '1';
        bits[3][0] = '0';
    }
    else
    {
        gcodes(n-1);
        // generate bit j (from n-1 down to 1) for codes up to x-1
        for (i=0, j=n; --j; i=x/2)
            for (; i<x; i++)
                bits[i][j] = bits[i/2][j-1];
        // replicate bit 0 for codes up to x-1
        for (; i<x; i++)
            bits[i][0] = bits[i%4][0];
    }

    for (i=0; i<x; i++, printf("\n"))
        for (j=n; j--; )
            printf("%c", bits[i][j]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM