2

基数10の数値を基数31に変換したい

これらの文字のみを使用したいと思います。23456789abcdefghjkmnpqrstuvwxyz

ご覧のとおり、5文字は除外されています(これらは必要ありません)。1 0 o l i

私が今持っている機能は以下の通りですが、もちろんそれは機能しません。2を入力すると、4が出力されます。の出力はtenTo31(2)2である必要があります。

function tenTo31($num)
{
    $out   = "";
    $alpha = "23456789abcdefghjkmnpqrstuvwxyz";

    while($num > 30)
    {
        $r = $num % 31;
        $num = floor($num / 31) - 1;
        $out = $alpha[$r] . $out;
    }

    return $alpha[$num] . $out;
}

これを機能させる方法について何かアイデアはありますか?

4

6 に答える 6

4

これはあなたが望むものについての盲目的な推測です:

$alpha = "yz23456789abcdefghjkmnpqrstuvwx";
于 2009-10-20T07:42:31.287 に答える
4

あるベースから別のベースに変換するための組み込み関数base_convert()があります。アルファベットは固定されていますが、strtr()を使用して、これらの数字を独自の数字に置き換えることができます。

「tenTo31(2)の出力は2である必要があります」:1つの可能性は、「2」を再び3番目のシンボルにすることです。

function tenTo31($num) {
  static $from = "0123456789abcdefghijklmnopqrstu";
  static $to   = "yz23456789abcdefghjkmnpqrstuvwx";
  return strtr(base_convert($num, 10, 31), $from, $to);
}

for($i=0; $i<31; $i++) {
 echo $i, '=', tenTo31($i), ' | ';
 if ( 9===$i%10 ) echo "\n";
}

プリント

0=y | 1=z | 2=2 | 3=3 | 4=4 | 5=5 | 6=6 | 7=7 | 8=8 | 9=9 | 
10=a | 11=b | 12=c | 13=d | 14=e | 15=f | 16=g | 17=h | 18=j | 19=k | 
20=m | 21=n | 22=p | 23=q | 24=r | 25=s | 26=t | 27=u | 28=v | 29=w | 
30=x |

編集:base(31)番号を10進数に戻すには、最初に変換(strtr)を逆にしてから、base_convert(..、31、10)を呼び出す必要があります。base(31)からの変換とbase(31)への変換を1つの関数に組み合わせることができます。

function convert_ten_31($num, $numIsDecimal) {
  static $default = "0123456789abcdefghijklmnopqrstu";
  static $symbols = "yz23456789abcdefghjkmnpqrstuvwx";

  if ( $numIsDecimal ) {
   return strtr(base_convert($num, 10, 31), $default, $symbols);
  }
  else {
   return base_convert(strtr($num, $symbols, $default), 31, 10);
  } 
}

// testing
for($i=0; $i<10000; $i++) {
 $x = convert_ten_31($i, true);
 $x = convert_ten_31($x, false);

 if ( $i!==(int)$x ) {
  var_dump($i, $x);
  die;
 }
}
echo 'done.';

シンボルをパラメーターとして受け取るbase_convert()のような関数を自分で作成することも簡単にできます。したがって、tenTo30()、tenTo31()、tenTo32()、...の代わりに1つの柔軟な関数を使用できます。

于 2009-10-20T07:43:41.803 に答える
2

1文字と0文字を使用していません。ナンバリングシステムの最初の桁は2です。つまり、2は基数10の0に相当します。3は基数10の1に相当し、4は基数10の2に相当します。

于 2009-10-20T07:19:05.333 に答える
1

なぜあなたは32までにモジュールを取っているのですか?%31と/31を使用する必要があります。10進数では10進数のモジュールを使用しているので、31進数である必要があります。しかし、これを忘れた場合、ロジックは正しいと思います。「変更された数字」を使用すると、基数10の2が基数31の4に等しい理由がわかりません。

于 2009-10-20T07:20:52.067 に答える
0

学習演習のアルゴリズムを続行することをお勧めしますが、作業を完了する必要がある場合は、 base_convertの使用を検討してください。

于 2009-10-20T07:43:46.417 に答える
0

http://www.crockford.com/wrmg/base32.htmlによるマッピングは次のようになります。

function symbolToEncode ($num) {
    $out   = "";
    static $alpha = "0123456789ABCDEFGHJKMNPQRSTVWXYZ*~$=U";

    while ($num >= 37) {
        $r = $num % 37;
        $num = floor ($num / 37);
        $out = $out . $alpha[$r];
    }

    return $out . $alpha[$num];
}

function decodeToEncode ($str) {
  static $from = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*~=$";
  static $to   = "0123456789ABCDEFGH1JK1MN0PQRSTUVWXYZABCDEFGH1JK1MN0PQRSTUVWXYZ*~=$";
  return strtr ($str, $from, $to);
}

明らかに本当の課題はencodeToSymbol()関数を書くことです。私は実際にはPHPの専門家ではないので(文字列内の$は、おそらく何らかの方法でエスケープする必要があります-ヒント?)、それは他の人に任せます。

于 2009-10-20T08:15:57.480 に答える