まず初めに、猿の成長軌跡シリーズを楽しみに待ってくださっている小さなお友達の皆様、大変申し訳ございませんが、春節も近づいており、もう少し時間がかかるかもしれませんが、すでに原稿は執筆中で、公開は終了とさせていただきます。春祭りの後にリリースされます
。手を練習するためのブルーブリッジカップについての質問、ねえ、質問を見つけました、あまり言うことはありません、質問に行きましょう
トピック
n 個の数値を入力し、16 進数から 8 進数に変換する必要があるという、わかりやすいトピックです。一般的な慣行もここで提案されているとおりです。最初に 10 進数に変換し、次に 8 進数に変換する必要がありますが、最初に 10 進数に変換すると、コンピューターの計算能力が無駄になり、アルゴリズムの時間計算量が増加すると思いますが、この変換は完全に最適化できます。
私の最適化アルゴリズムのアイデア
私のアルゴリズムは 16 進数を 8 進数に直接変換するもので、このアルゴリズムには次の要件があります。
- 入力内容は文字列なので、大量の操作を実行できます。
- アルゴリズムの時間と空間の複雑さを軽減するために使用できる for ループは最大でも 1 つだけです。
- 戻り値も文字列です
私のアルゴリズムを紹介しましょう:
- 入力文字列を文字配列に変換します。
- 下位ビット (つまり、配列の最上位ビット) から始めて、次の操作を実行します。
1. 16 進数から 8 進数に変換されるため、データの一貫性を保つために、8 進数の各桁の数は次のようにみなします。元の数の同じ位置にある 2 乗算、わかりにくいかもしれないので例をあげます、 (10) 16 = (16) 10 = (20) 8 ここで 16 進数の最初の桁(下から2桁目)が1、8進数にすると2、つまり1*2の1乗となり、(100)16=(256)10=(400)10、ここではは 16 進数の最初の桁(下から 3 桁目)は 1、8 進数では 4、つまり 1 * 2 の 2 乗、というようになります。
2. ただし、下位ビットは上位ビットのキャリーと同様であることに注意してください。ここでのキャリー数は保存する必要があります。保存するには incr パラメータを使用します。変換時に下位ビットから上位ビットへのキャリーを追加する必要があります。 。
3. さらに、現在のビットの数値は変換されています (2 の累乗で乗算) + キャリーは 8 を超える可能性があります。この時点で、8 未満の最終値を取得するには剰余演算を実行する必要があります。 、これは 8 進数のビット番号です。次の操作を容易にするために、キャリー ビットも保存し続ける必要があります。
4. 手順 1 ~ 3 に従って、下位ビットから上位ビットまでの各ビットの 8 進結果を計算します。ただし、最初の桁に桁上げが含まれる場合があります。このとき、桁上げの処理が必要です。この方法はステップ 2 ~ 3 と同様です。
コード
package hexToOct;
public class HexToOct {
/**
* 十六进制转八进制
* 原理:1. 从低位往高位处理,每升一位*2
* @param args
*/
private static String hexToOct(String hex) {
char[] ch = hex.toCharArray(); //step1
StringBuilder builder = new StringBuilder();
int i = 0, incr = 0; // incr - 累进数, rest - 余数
//step2
for (int j = ch.length-1; j>= 0; j--) {
int numb = 0;
// 将十六进制转10进制
if (ch[j] >= '0' && ch[j] <= '9') {
numb = Integer.valueOf(ch[j] - '0');
} else if(ch[j] >= 'A' && ch[j] <= 'F') {
numb = Integer.valueOf(ch[j] - 'A') + 10;
} else {
System.out.println("请输入十六进制数");
return null;
}
// 处理每一位上的数字
numb = numb << (i++); // numb = numb * (2^i); i = i + 1;
numb += incr;
incr = numb / 8; // 求累进数,便于加入下一次的运算
numb = numb % 8; // 求当前的余数
builder.append(numb + "");
}
//考虑首位进位的情况
int rest = 0;
if (incr != 0) {
while(incr > 0) {
rest = incr % 8;
incr = incr / 8;
builder.append(rest + "");
}
}
return builder.reverse().toString();
}
public static void main(String[] args) {
System.out.println(hexToOct("8A24B"));
}
}
演算結果
2121113
アルゴリズムの複雑さ
の上)