6 Stimmen

Python - Hausaufgaben - Umwandlung einer beliebigen Basis in eine beliebige Basis

Ich versuche, ein Programm zu erstellen, das eine Zahl in einer beliebigen Basis in eine andere Basis nach Wahl des Benutzers umwandelt. Der Code, den ich bis jetzt habe, geht wie folgt:

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: "))

Dies sind die Daten, die ich vom Benutzer erhalte. Die Ausgangszahl, ihre Ausgangsbasis und die Basis, in die der Benutzer umrechnen möchte. So wie ich es verstehe, muss ich zur Basis 10 konvertieren und dann in die gewünschte Basis, die der Benutzer angibt.

An dieser Stelle stoße ich auf eine Mauer: Ich muss die äußerste linke Ziffer der Ausgangszahl mit ihrer Ausgangsbasis multiplizieren, dann die nächste Ziffer rechts daneben addieren und das Ganze wiederholen, bis ich die äußerste rechte Ziffer erreiche. Ich weiß, wie man das auf dem Papier macht, aber ich habe keine Ahnung, wie ich das in Python-Code umsetzen soll. Ich bin mir nicht sicher, wie ich die erste Zahl multiplizieren und dann die nächste addieren soll, und ich weiß auch nicht, wie ich dem Programm mitteilen kann, wann es mit dieser Operation aufhören soll.

Ich verlange nicht, dass das Programm für mich geschrieben wird, aber ich möchte gerne einen Hinweis auf die richtige Richtung erhalten.

Vielen Dank für Ihre Zeit!

0voto

int() kann Zeichenketten aus jeder Basis zwischen 2 und 36 konvertieren. Wenn Sie einen größeren Bereich benötigen, erstellen Sie eine Zeichenkette, die die Ziffern enthält, und verwenden Sie die index() Methode, um den Wert zu erhalten.

0voto

Shaheem TP Punkte 1

Ich habe hier nach Abkürzungen gesucht, aber es scheint keine zu geben. Hier sind also die langen Methoden, die ich gefunden habe. Diese Antwort basiert auf einer Antwort unter Quora und auch im Zusammenhang mit anderen Antworten hier.

Der einfachste Weg (wahrscheinlich) ist es, eine beliebige Zahl von einer Basis b1 nach b2 zu konvertieren, indem man b1Decimalb2 konvertiert.

Eine Zahl zur Basis b1 kann wie ein Polynom zur Basis b1 behandelt werden,

d.h., eine 4-stellige Zahl abcd = d*(b1^0)+c*(b1^1)+b*(b1^2)+a*(b1^3)

Beispiel: 123(Dezimal) = 3*(10^0)+2*(10^1)+1*(10^2)

Um also von einer beliebigen Basis in Dezimal zu konvertieren, muss man die Summe aller [digit*(base^power)] (wobei die Potenz 0 bis [NumOfDigits-1] beträgt) in umgekehrter Reihenfolge der Ziffern. Behandeln Sie dazu die Zahl wie eine string und durchlaufen sie mit einer for Schleife.

Die Eingabe sollte also ein string und die Operation an int .

Der nächste Schritt ist die Umrechnung einer Dezimalzahl D in die Basis b2.

Teilen Sie D/b2, der Rest ist die Ziffer ganz rechts. Dividiere den Quotienten durch b2, der Rest ist diesmal die nächste Ziffer ganz rechts. Wiederholen Sie diesen Zyklus, bis der Quotient 0 ist.

Beispiel,

8(Dez) nach Binär:

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(Dez)=1000(Bin)

Dazu wird die ausgegebene Zahl als Zeichenkette behandelt und die Zeichenkette nach der Verkettung aller Ziffern umgedreht. (Siehe oben: '0' + '0' + '0' + '1' ='0001' umgedreht '1000'.

Für diese beiden Prozesse würde das folgende Python-Programm ausreichen:

    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]))

Sie werden jedoch feststellen, dass dieses Programm bei der Verwendung von Basen mit mehr als 10 nicht praktisch ist. Zu diesem Zweck müssen Sie mehr Ziffern verwenden, um Werte von mehr als 0-9 darzustellen. Hierfür müssen Sie lange if-else Leitern, um die Ziffern entsprechend dem Nennwert auszuwählen oder umgekehrt.

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]))

Fast jeder vermeidet diese lange if-else Leiter unter Verwendung eines Wörterbuchs mit den Flächenwerten als Schlüssel und den Symbolen/Ziffern als deren jeweilige Werte. Jetzt wird das Programm:

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])

Hier sind Ihre Hausaufgaben. Wählen Sie eine dieser drei Methoden.

Um noch mehr Basen zu verwenden, können Sie einfach das Wörterbuch erweitern und ein langes Wörterbuch wie @ erstellen Noctis-Skytower .

Jede einzelne Website, die ich überprüfte, hatte lange Wörterbücher wie dieses, aber ich neige dazu, für fast alles Abkürzungen zu verwenden. Ich benutzte einfache range() Funktion, if-else Anweisungen, und einfache for Schleifen, um den Prozess zu verkürzen (aber ich denke, es sieht ein bisschen verwirrend aus, obwohl es einfach ist). Der Vorteil ist, dass es sehr einfach ist, weitere Basen hinzuzufügen, indem man einfach einen Schlüssel hinzufügt, range(a,b) für den Bereich der Nennwerte von Ziffern und einen Wert, range(x,y) für den Bereich der Unicode-Werte der Zeichen für die jeweiligen Werte.

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])

Dies kann auch über Funktionen geschehen:

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))

Wenn Sie nun das Wörterbuch erweitern können, können Sie wahrscheinlich von jede Basis zu jede Basis.

Dies sind einige Shortcuts, die ich auf anderen StackOverflow Q-A und anderen Websites gefunden habe:

Um Zahlen von einer beliebigen Basis zwischen 2 und 36 in Dezimalzahlen umzuwandeln: 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

Zur Umwandlung von Dezimal in Binär, Oktal und Hex:

>>> bin(8)
'0b1000'
>>> oct(8)
'0o10'
>>> hex(8)
'0x8'

Ich hoffe, das TL;DR jemandem geholfen. Wenn jemand auf Fehler hinweisen, den Text überarbeiten oder kürzere Methoden anbieten kann, wäre ich dankbar.

-2voto

Luca Sans S Punkte 122

Ganz einfach. Zuerst habe ich eine number.py

class number:
    def __init__(self, value: str, base):
        alphabet = [str(i) for i in range(10)] + [chr(i).upper() for i in range(97, 123)]
        self.val = [c for c in value]
        self.alph = alphabet[:base]
        self.last = self.alph[-1]
        self.first = self.alph[0]
        self.len_alph = len(alphabet)

    def last_that_is_not(self,number, target):
        for idx, c in enumerate(number[::-1]):
            if c != target: return len(number)-1 - idx
        return

    def next(self):
        # We look for the last letter that isn't equal to self.last
        change_loc = self.last_that_is_not(self.val, self.last)
        if change_loc is not None:
            elem = self.val[change_loc]
            new_letter = self.alph[self.alph.index(elem)+1]
            self.val[change_loc] = new_letter
        len_val = len(self.val)
        # In case last that is not isnt the last letter
        change_loc = -1 if change_loc is None else change_loc
        increment = change_loc == -1
        for idx in range(change_loc+1, len_val):
            self.val[idx] = self.alph[0]
        if increment:
            self.val = [self.alph[1]] + [self.alph[0] for i in range(len_val)]

    def prev(self):
        # we look for the last letter that isn't equal to self.first
        change_loc = self.last_that_is_not(self.val, self.first)
        if change_loc is not None:
            elem = self.val[change_loc]
            new_letter = self.alph[self.alph.index(elem)-1]
            self.val[change_loc] = new_letter
        len_val = len(self.val)
        # In case last that is not is first letter
        self.val = [alphabet[-1] for i in range(len_val - 1)]

    def __repr__(self):
        return ''.join(self.val)
    __str__ = __repr__

dann main.py

#!/usr/bin/pypy3
from time import time
from math import log, ceil
from number import number as num_baseX

# converts a number from base base to base 10
def convert2int(number, base = 10):
    number = number.upper()
    result = 0
    l = int(base**(len(number) - 1))
    for n in number:
        if '0' <= n <= '9':
            result += l*(ord(n) - ord('0'))
        else:
            result += l*(ord(n) - 55)
            # ord('A') - 10 = 55
        l = round(l/base)
    return result

# convertit un nombre de base 10 en
# un nombre de base base, base <= 36
def base10toX(number: int, base=10):
    start = ''.join(['0' for _ in range(ceil(log(number, base)))])
    start = '0'
    result = num_baseX(start, base)
    def _wrapper(number: int, base = 10):
        nonlocal result
        log_num = int(log(number, base))
        for i in range(base**log_num):
            result.next()
        number = number - base**log_num
        if number > 0:
            _wrapper(number, base)
    _wrapper(number, base)
    return result

def baseXtoY(**kwargs):
    """
    Usage:
    baseXtoY(num, X, Y)
    num = number
    X = base of num
    Y = base to convert to
    """
    integer_num = convert2int(kwargs['num'], kwargs['X'])
    return base10toX(integer_num, kwargs['Y'])

HINWEIS: Ich, L. Pham-Trong, habe diesen Code geschrieben. Er ist durch die 4-close BSD-Lizenz geschützt:

Copyright (c) 2021, Luca PHAM-TRONG
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
   list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

3. All advertising materials mentioning features or use of this software must
   display the following acknowledgement:
     This product includes software developed by L. Pham-Trong, and this guy rocks.

4. Neither the name of the copyright holder nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY COPYRIGHT HOLDER "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X