0

カウントの目的で任意の数字を使用するカウンターアルゴリズムが必要です。

私のコードはこれに似ています:

static char digits[] = {'x','y','z'}; /* Arbitrary number of arbitrary digits. */
int i;
for(i=0; i<100; i++) {
    printf("%s\n", get_next());
}

私の期待する出力:

x
y
z
yx
yy
yz
zx
zy
zz
yxx
yxy
yxz
yyx
yyy
yyz
yzx
yzy
yzz
zxx
... and so on

ご覧のとおり、関数を実装するためのアルゴリズムが必要なget_next()ので、C言語を使用することは重要ではありません。

明確にするためにIを編集します。

私のget_next()関数はこれに似ているかもしれません:

char get_next() {
    static previous = digits[0];
    char *next_number;

    /* do something here using previous and digits[] */

    return next_number;
}

get_next(void)次の番号を生成する関数にまたはnext(previous_number)またはnext(digits, previous_number)プロトタイプを使用することは、私にとって重要ではないことに注意してください。

明確にするためにIIを編集します。

私の実際のシナリオは、上記の単純な例からより複雑です。任意の任意の桁で機能する一般的なソリューションが必要です。

数字入力の例:

static char digits[] = {'a', 'b', 'c', ... 'z', '0', '1', ...}; /* Lots of digits */
static char digits[] = {'s','t','a','c','k','o','v','e','r'};   /* Arbitrary sequence */
4

4 に答える 4

5

とても簡単です。ベースのdigit_countに変換してから、数字を数値に変換する代わりに、配列にインデックスを付けます。

任意の底に変換するには、除算と剰余が必要です。

これは、以前に使用したバージョンよりも優れたバージョンです。これは、実際にバッファーを作成し(出力するのではなく)、反復のために再帰をドロップし、以前のC/PythonホッジポッドではなくCであるためです。

静的バッファーを使用するため、コードはスレッドセーフではありません。また、数値が大きすぎる場合にコードがバッファをアンダーフローしないことを確認するエラーがないことにも注意してください。最後に、文字列を最後から前に構築し、バッファの中央にポインタを返すというトリックを使用して、最後の数字を逆にする必要がないようにします。

char *getnum(int x)
{
    static char buffer[1024];
    int idx = 1024;

    buffer[--idx] = '\0';

    if (x == 0)
        buffer[--idx] = digits[0];
    else
    {
        while (x != 0)
        {
            buffer[--idx] = digits[x % digit_count];
            x /= digit_count;
        }
    }    

    return buffer + idx;
}
于 2009-12-22T07:01:21.590 に答える
2

あなたの質問は2つの部分に分けることができます:

  1. 整数を任意の基数、、nおよびの表現に変換します。
  2. 与えられたn記号は、上の表現を印刷します。

2番目の部分は明らかに非常に簡単です。特定のベースに数値の表現があり、そのようなベースで使用する記号がある場合、それらを印刷することは、単にループで物事を印刷することです。

特定の基数で整数の表現を取得するには、intsの配列を使用します。値は数字を表し、インデックスは場所を表します。また、有効な桁数を保存する必要があります。また、正の数のみを扱っていると想定しています。これは、質問で提案されているように思われるためです。

#define MAX 128 /* maximum number of digits in the final representation */

/* abstract representation of a number in a given base.
   `n` is the number of valid digits in the representation, and
   `digits` stores the digits in reverse order */
struct rep {
    int digits[MAX]; /* change as needed, or dynamically allocate */
    size_t n;
};

次に、数値をその表現に変換する関数を作成しましょう。逆の表現を返す方が簡単なので、それを返し、逆の順序で印刷します。

/* convert a number `n` to its (reversed) representation in base `base`,
   and return the result in `ret`. */
void convert(int n, size_t base, struct rep *ret)
{
    size_t i = 0;
    do {
        ret->digits[i++] = n % base;
        n /= base;
    } while (n > 0 && i < MAX);
    ret->n = i;
}

これが終わったら、表現を出力する関数を書いてみましょう。

/* return a string representation of `num` in base `ndigits`, with `digits`
   representing the symbols */
char *next(const char *digits, size_t ndigits, int num)
{
    struct rep r;
    static char ret[MAX+1];
    size_t i;
    convert(num, ndigits, &r);
    if (r.n == MAX)
        return NULL;
    for (i=r.n; i; --i)
        ret[r.n-i] = digits[r.digits[i-1]];
    ret[r.n-i] = 0;
    return ret;
}

次に、ドライバープログラムを作成できます。

int main(void)
{
    const char digits[] = {'x','y','z'};
    size_t ndigits = sizeof digits / sizeof digits[0];
    int i;
    for (i=0; i < 100; i++) {
        char *data = next(digits, ndigits, i);
        if (data)
            printf("%s\n", data);
        else
            fprintf(stderr, "%d, error converting\n", i);
    }
    return 0;
}

私はそれらが互いに独立しているように(私が逆の表現を使用しているという明白な単純化を除いて)上記convertを書きました。nextこれにより、他のプログラムで簡単に使用できます。

于 2009-12-22T09:03:10.657 に答える
0
char *get_next()
{
  static char str[10];
  static int i=0;
  int radix = 3; // size of array
  itoa(i,str,radix); // create base-3 representation
  char *p = &str[0];
  while( *p )
  {
    *p = digits[*p-'0']; // convert to the xyz scheme, breaks if radix>10
    p++;
  }
  i++;
  return str;
}
于 2009-12-22T06:54:03.553 に答える
0

代わりにget_nextをオーバーロードする必要があるようですoperator++。これは次の派生につながります。それは、これは別のオブジェクトでなければならないということです。

「数字」を10進数に変換し、それを操作してから、元に戻します。

于 2009-12-22T23:05:06.457 に答える