Python-宿題 - 任意のベースを任意のベースに変換する
-
09-10-2019 - |
質問
任意のベースの番号をユーザーの選択の別のベースに変換するプログラムを作成しようとしています。私がこれまでに持っているコードは次のようになります:
innitvar = float(raw_input("Please enter a number: "))
basevar = int(raw_input("Please enter the base that your number is in: "))
convertvar = int(raw_input("Please enter the base that you would like to convert to: "))
これらは私がユーザーから得たデータです。初期番号、その初期ベース、およびユーザーが変換したいベース。私が理解しているように、私はベース10に変換し、次にユーザーが指定する目的のベースに変換する必要があります。
これは、レンガの壁に当たったところです。初期数の左端の数字を初期ベースで掛け、次の数字を右に追加してから、右端の数字に達するまで繰り返す必要があります。紙の上でこれを行う方法は理解していますが、Pythonコードに入れる方法はわかりません。最初の数字をどのように掛けてから次の番号を追加するかはわかりません。また、この操作の実行を停止するタイミングをプログラムに知らせる方法も理解していません。
私はプログラムを書いてもらうことを求めていませんが、正しい方向に向けられたいと思います。
御時間ありがとうございます!
解決
これはあなたの問題に対する答えの前半でなければなりません。ベースに変換する方法を把握できますか?
# Create a symbol-to-value table.
SY2VA = {'0': 0,
'1': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5,
'6': 6,
'7': 7,
'8': 8,
'9': 9,
'A': 10,
'B': 11,
'C': 12,
'D': 13,
'E': 14,
'F': 15,
'G': 16,
'H': 17,
'I': 18,
'J': 19,
'K': 20,
'L': 21,
'M': 22,
'N': 23,
'O': 24,
'P': 25,
'Q': 26,
'R': 27,
'S': 28,
'T': 29,
'U': 30,
'V': 31,
'W': 32,
'X': 33,
'Y': 34,
'Z': 35,
'a': 36,
'b': 37,
'c': 38,
'd': 39,
'e': 40,
'f': 41,
'g': 42,
'h': 43,
'i': 44,
'j': 45,
'k': 46,
'l': 47,
'm': 48,
'n': 49,
'o': 50,
'p': 51,
'q': 52,
'r': 53,
's': 54,
't': 55,
'u': 56,
'v': 57,
'w': 58,
'x': 59,
'y': 60,
'z': 61,
'!': 62,
'"': 63,
'#': 64,
'$': 65,
'%': 66,
'&': 67,
"'": 68,
'(': 69,
')': 70,
'*': 71,
'+': 72,
',': 73,
'-': 74,
'.': 75,
'/': 76,
':': 77,
';': 78,
'<': 79,
'=': 80,
'>': 81,
'?': 82,
'@': 83,
'[': 84,
'\\': 85,
']': 86,
'^': 87,
'_': 88,
'`': 89,
'{': 90,
'|': 91,
'}': 92,
'~': 93}
# Take a string and base to convert to.
# Allocate space to store your number.
# For each character in your string:
# Ensure character is in your table.
# Find the value of your character.
# Ensure value is within your base.
# Self-multiply your number with the base.
# Self-add your number with the digit's value.
# Return the number.
def str2int(string, base):
integer = 0
for character in string:
assert character in SY2VA, 'Found unknown character!'
value = SY2VA[character]
assert value < base, 'Found digit outside base!'
integer *= base
integer += value
return integer
これが解決策の後半です。これら2つの機能を使用することにより、ベースの変換は非常に簡単です。
# Create a value-to-symbol table.
VA2SY = dict(map(reversed, SY2VA.items()))
# Take a integer and base to convert to.
# Create an array to store the digits in.
# While the integer is not zero:
# Divide the integer by the base to:
# (1) Find the "last" digit in your number (value).
# (2) Store remaining number not "chopped" (integer).
# Save the digit in your storage array.
# Return your joined digits after putting them in the right order.
def int2str(integer, base):
array = []
while integer:
integer, value = divmod(integer, base)
array.append(VA2SY[value])
return ''.join(reversed(array))
すべてをまとめた後、以下のプログラムになってしまうはずです。時間をかけてそれを理解してください!
innitvar = raw_input("Please enter a number: ")
basevar = int(raw_input("Please enter the base that your number is in: "))
convertvar = int(raw_input("Please enter the base that you would like to convert to: "))
# Create a symbol-to-value table.
SY2VA = {'0': 0,
'1': 1,
'2': 2,
'3': 3,
'4': 4,
'5': 5,
'6': 6,
'7': 7,
'8': 8,
'9': 9,
'A': 10,
'B': 11,
'C': 12,
'D': 13,
'E': 14,
'F': 15,
'G': 16,
'H': 17,
'I': 18,
'J': 19,
'K': 20,
'L': 21,
'M': 22,
'N': 23,
'O': 24,
'P': 25,
'Q': 26,
'R': 27,
'S': 28,
'T': 29,
'U': 30,
'V': 31,
'W': 32,
'X': 33,
'Y': 34,
'Z': 35,
'a': 36,
'b': 37,
'c': 38,
'd': 39,
'e': 40,
'f': 41,
'g': 42,
'h': 43,
'i': 44,
'j': 45,
'k': 46,
'l': 47,
'm': 48,
'n': 49,
'o': 50,
'p': 51,
'q': 52,
'r': 53,
's': 54,
't': 55,
'u': 56,
'v': 57,
'w': 58,
'x': 59,
'y': 60,
'z': 61,
'!': 62,
'"': 63,
'#': 64,
'$': 65,
'%': 66,
'&': 67,
"'": 68,
'(': 69,
')': 70,
'*': 71,
'+': 72,
',': 73,
'-': 74,
'.': 75,
'/': 76,
':': 77,
';': 78,
'<': 79,
'=': 80,
'>': 81,
'?': 82,
'@': 83,
'[': 84,
'\\': 85,
']': 86,
'^': 87,
'_': 88,
'`': 89,
'{': 90,
'|': 91,
'}': 92,
'~': 93}
# Take a string and base to convert to.
# Allocate space to store your number.
# For each character in your string:
# Ensure character is in your table.
# Find the value of your character.
# Ensure value is within your base.
# Self-multiply your number with the base.
# Self-add your number with the digit's value.
# Return the number.
integer = 0
for character in innitvar:
assert character in SY2VA, 'Found unknown character!'
value = SY2VA[character]
assert value < basevar, 'Found digit outside base!'
integer *= basevar
integer += value
# Create a value-to-symbol table.
VA2SY = dict(map(reversed, SY2VA.items()))
# Take a integer and base to convert to.
# Create an array to store the digits in.
# While the integer is not zero:
# Divide the integer by the base to:
# (1) Find the "last" digit in your number (value).
# (2) Store remaining number not "chopped" (integer).
# Save the digit in your storage array.
# Return your joined digits after putting them in the right order.
array = []
while integer:
integer, value = divmod(integer, convertvar)
array.append(VA2SY[value])
answer = ''.join(reversed(array))
# Display the results of the calculations.
print answer
他のヒント
初期数の左端の数字を無効なベースで掛け、次の数字を右に追加してから、右端の数字に達するまで繰り返す必要があります。
したがって、数字を取得する必要があります。リスト内。
ヒント1:使用 divmod()
数字を数字に分割する機能。 10で除算して、小数桁を取得します。
ヒント2:while n > 0:使用できます divmod()
商と残りを取得するには。リストに残りを保存し、次の値として商を使用した場合 n 残りがゼロになり、完了するまで、あなたの番号は小さくなります。
ヒント3:数字が右から左に到着します。使用する reverse
これのリストの順序を切り替えるには、あなたを悩ませます。または、使用してリストを作成します insert(0,digit)
.
これで数字ができました。リスト内。リストを繰り返すことができます。
試してみてください for
サイズの声明。
「マルチと追加」ループを使用する必要がある場合があります。 total = total * new_base + next_digit
ループの本体がしばしば見える方法です。
ただの学生、あなたが必要なもののアイデアで速度を落としてください。必要だと思うものは必要ないかもしれません。
最初から始めます:ユーザーは番号を入力します。ユーザーはベースを入力します。これらはどちらも文字列です。ベースが12で、数は1AB3であるとします。したがって、12^3の場所に「1」、12^2の場所に「a」、12^1に「b」、12^0(1)の「3」があります。ベース10でこの番号が必要な場合は、いくつかの番号を一緒に追加する必要があります。
具体的には、1*12^3 + 10*12^2 + 11*12^1 + 3*12^0を追加する必要があります。ここに何かに注意してください:あなたは3,2,1,0を持っています。これは、入力文字列1AB3の長さにうまく対応します。だからおそらくa for
ここではループが役立ちます。ユーザーは整数を入力せず、文字列を入力します。したがって、数字の数字ではなく、文字列からの文字が必要です。
シンボル「a」と「c」が小数表記で何を表しているかをどのように知るのですか? Noctis Skytowerの答えを見てください!
したがって、最初のタスクは、文字列を介して反復する方法を把握することです。 2番目のタスクは、文字列から個々の文字値を使用してNoctis Skytowerの回答で辞書にアクセスする方法を把握することです。3番目のタスクは、その情報を利用するループを作成する方法を把握することです。
2つの関数を記述する必要があります。スキームで(私はPython:Pよりもはるかによくスキームを知っているので)、これらの2つの関数は呼び出されます string->number
と number->string
, 、もちろん、あなたが好きなものは何でも名前を付けることができます。
これらの各関数は、変換を行うためにベースパラメーターを使用する必要があります。必要に応じて、デフォルトに10にすることができます。
それらのそれぞれを正常に実装すると、残りはケーキになります。
あなたのためのテストケース:
assert str2num('1234', 10) == 1234
assert str2num('1234', 16) == 0x1234
assert num2str(1234, 10) == '1234'
assert num2str(1234, 16) == '4d2'
assert num2str(0x1234, 16) == '1234'
ショートカットを探してここに来ましたが、何も存在しないようです。だからここに私が見つけた長い方法があります。この答えは、の答えに基づいています Quora また、ここでの他の答えにも関連しています。
最も簡単な方法(おそらく)は、任意の数をベースB1からB2に変換することです。B1→小数→B2を変換することです。
ベースB1の数は、ベースB1の多項式のように扱うことができます。
つまり、4桁の数abcd = d*(b1^0)+c*(b1^1)+b*(b1^2)+a*(b1^3)
例:123(10進)= 3*(10^0)+2*(10^1)+1*(10^2)
したがって、任意のベースから小数に変換するには、すべての合計を見つけます [digit*(base^power)]
(ここで、電力は0から[numofdigits-1]です) 数字の逆の順序で。このために、数をaとして扱います string
aを使用して繰り返します for
ループ。
したがって、入力はaにする必要があります string
そしてop an int
.
次のステップは、10進数dをベースB2に変換することです。
D/B2を分割すると、残りは右端の数字です。商をB2で除算し、残りは次の右端の数字です。商が0になるまでこのサイクルを繰り返します。
例えば。、
8(dec)へのバイナリ:
8/2=4; 8%2=0
4/2=2; 4%2=0
2/2=1; 2%2=0
1/2=0; 1%2=1
8(dec)= 1000(ビン)
これは、出力番号を文字列として扱い、すべての数字を連結した後に文字列を逆にすることによって行われます。 (上記を参照: '0' + '0' + '0' + '1' ='0001'
、それを逆🠢 '1000'
これらの2つのプロセスについて、次のPythonプログラムが行います。
N=input("Num:")
B1=int(input("FromBase:"))
B2=int(input("ToBase:"))
print("Base[",B1,"]:",N)
#From Base B1 to Decimal
DN=0
for i in range(len(N)):
DN+= int(N[::-1][i]) * (B1 ** i)
print("Decimal:",DN)
#From Decimal to Base B2
if int(N) == 0:
BN = 0
else:
BN = ""
while DN > 0:
BN += str(DN % B2)
DN = int(DN / B2)
print("Base[",B2,"]:",int(BN[::-1]))
ただし、10を超えるベースを使用している間、このプログラムは実用的ではないことがわかります。この目的のために、0〜9を超える値を表すためにより多くの数字を使用する必要があります。そのためには、長く使用する必要があります if-else
はしご、額面に応じて数字を選択するか、Viseの逆になります。
N=input("Num:")
B1=int(input("FromBase:"))
B2=int(input("ToBase:"))
print("Base[",B1,"]:",N)
#From Base B1 to Decimal
DN=0
for i in range(len(N)):
if N[::-1][i] == '0':
DN += 0 * (B1 ** i)
elif N[::-1][i] == '1':
DN += 1 * (B1 ** i)
elif N[::-1][i] == '2':
DN += 2 * (B1 ** i)
''' :
: '''
elif N[::-1][i] == 'A':
DN += 10 * (B1 ** i)
''' :
: (fill it) ....
: '''
print("Decimal:",DN)
#From Decimal to Base B2
if int(N) == 0:
BN = 0
else:
BN = ""
while DN > 0:
R = DN % B2
if R==0:
BN += '0'
elif R==1:
BN += '1'
elif R==2:
BN += '2'
''' :
:
: '''
elif R==10:
BN += 'A'
''' :
:
: '''
DN = int(DN / B2)
print("Base[",B2,"]:",int(BN[::-1]))
ほとんどの人がこれを避けています if-else
はしごキーとして面面した辞書を使用し、それぞれの値としてシンボル/数字を使用します。これでプログラムは次のようになります。
Dig={0: '0', 1: '1', 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: 'I', 19: 'J'}
N=input("Num:")
B1=int(input("FromBase:"))
B2=int(input("ToBase:"))
print("Base[",B1,"]:",N)
#From Base B1 to Decimal
DN=0
for i in range(len(N)):
for fv in Dig:
if Dig[fv]== N[::-1][i]: # FaceValue of the Digit
DN+= fv * (B1 ** i)
print("Decimal:",DN)
#From Decimal to Base B2
if N == '0':
BN = 0
else:
BN = ""
while DN > 0:
BN += Dig[DN % B2] # Digit for the Value
DN = int(DN / B2)
print("Base[",B2,"]:",BN[::-1])
homeworkあなたの宿題はあります。それらの3つの方法の任意を選択します。
さらに多くのベースを使用するには、辞書を展開して @のような長いものを作成することができますNoctis Skytower.
私がチェックしたすべてのウェブサイトにはそのような長い辞書がありましたが、私はほとんどすべてにショートカットを使用する傾向があります。シンプルを使用しました range()
働き、 if-else
声明、そしてシンプル for
プロセスを短くするためのループ(ただし、単純であるにもかかわらず、少し混乱しているように見えると思います)。これの利点は、キーを追加するだけでベースを追加するのが非常に簡単であることです。 range(a,b)
, 、数字の顔面図と値の範囲については、 range(x,y)
, 、それぞれの値の文字のユニコード値の範囲について。
Val = {range(10):range(48, 58), range(10,36): range(65, 91)}
N=input("Num:")
B1=int(input("FromBase:"))
B2=int(input("ToBase:"))
print("Base[",B1,"]:",N)
#From Base B1 to Decimal
DN = 0
for i in range(len(N)):
for j in Val:
if ord(N[i]) in Val[j]:
FV=j[ord(N[i])-Val[j][0]] # FaceValue of the Digit
if FV>= B1: # Digits aren't >=Base, right?
print("Base Error..")
exit()
else:
DN += FV * (B1 ** (len(N) - 1 - i))
print("Decimal:",DN)
#From Decimal to Base B2
if int(DN) == 0:
BN = '0'
else:
BN = ""
while DN > 0:
R = DN % B2
for i in Val:
if R in i:
BN+=chr(Val[i][R-i[0]]) #Finding the Digit for the Value
DN = int(DN / B2)
print("Base[", B2, "]:", BN[::-1])
これは、関数を使用して実行することもできます。
Val = {range(10):range(48, 58), range(10,36): range(65, 91)}
def B2D(N,B1):
'''From Base B1 to Decimal'''
DN = 0
for i in range(len(N)):
for j in Val:
if ord(N[i]) in Val[j]:
FV=j[ord(N[i])-Val[j][0]] # FaceValue of the Digit
if FV>= B1: # Digits aren't >=Base, right?
print("Base Error..")
exit()
else:
DN += FV * (B1 ** (len(N) - 1 - i))
return DN
def D2B(DN,B2):
'''From Decimal to Base B2'''
if int(DN) == 0:
BN = '0'
else:
BN = ""
while DN > 0:
R = DN % B2
for i in Val:
if R in i:
BN+=chr(Val[i][R-i[0]]) #Finding the Digit for the Value
DN = int(DN / B2)
return BN[::-1]
def B2B(N,B1,B2):
return D2B(B2D(N,B1),B2)
N=input("Num:")
B1=int(input("FromBase:"))
B2=int(input("ToBase:"))
print("Base[",B1,"]:",N)
print("Decimal:",B2D(N,B1))
print("Base[",B2,"]:",B2B(N,B1,B2))
これで、辞書を展開できれば、おそらくから変換できます どれか ベースに どれか ベース。 😎
これらは、他のStackOverFlow QAや他のWebサイトで見つけたいくつかのショートカットです。
2〜36の間の任意のベースから小数点までにnumsを変換するには: int(‘NumberString’,Base)
>>> int('1000',2)
8
>>> int('100',12)
144
>>> int('AA',17)
180
>>> int('Z',36)
35
>>> int('Z',37)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: int() base must be >= 2 and <= 36, or 0
小数をバイナリ、オクタル、ヘックスに変換するには:
>>> bin(8)
'0b1000'
>>> oct(8)
'0o10'
>>> hex(8)
'0x8'
これを願っています TL;DR
誰かを助けました。誰かが間違いを指摘したり、これを編集したり、より短い方法を提供したりすることができれば、感謝します。