programing

정수를 숫자로 분할하여 ISBN 체크섬 계산

yoursource 2021. 1. 16. 10:49
반응형

정수를 숫자로 분할하여 ISBN 체크섬 계산


나는 ISBN 번호의 검사 자리를 계산하는 프로그램을 작성 중입니다. 사용자의 입력 (ISBN 9 자리)을 정수 변수로 읽은 다음 마지막 숫자에 2를 곱하고 두 번째 마지막 숫자에 3을 곱해야합니다. 이 작업을 수행하기 위해 정수를 구성 자릿수로 "분할"하려면 어떻게해야합니까? 이것은 기본적인 숙제 연습이므로 목록을 사용해서는 안됩니다.


그것으로 문자열을 만드십시오.

myinteger = 212345
number_string = str(myinteger)

충분 해. 이제 반복 할 수 있습니다.

for ch in number_string:
    print ch # will print each digit in order

또는 슬라이스 할 수 있습니다.

print number_string[:2] # first two digits
print number_string[-3:] # last three digits
print number_string[3] # forth digit

또는 더 나은 방법은 사용자의 입력을 정수로 변환하지 않는 것입니다 (사용자가 문자열을 입력 함).

isbn = raw_input()
for pos, ch in enumerate(reversed(isbn)):
    print "%d * %d is %d" % pos + 2, int(ch), int(ch) * (pos + 2)

자세한 내용은 자습서를 읽으십시오 .


while number:
    digit = number % 10

    # do whatever with digit

    # remove last digit from number (as integer)
    number //= 10

루프가 반복 될 때마다 숫자에서 마지막 숫자를 제거하여에 할당합니다 digit. 역순, 마지막 숫자부터 시작하여 첫 번째로 끝남


list_of_ints = [int(i) for i in str(ISBN)]

정렬 된 정수 목록을 제공합니다. 물론, 덕 타이핑이 주어지면 str (ISBN)으로 작업하는 것이 좋습니다.

편집 : 주석에서 언급 했듯이이 목록은 오름차순 또는 내림차순이라는 의미로 정렬되지 않지만 정의 된 순서가 있습니다 (이론적으로 파이썬의 집합, 사전 등은 그렇지 않지만 실제로 순서는 경향이 있습니다) 상당히 신뢰할 수 있습니다). 정렬하려면 :

list_of_ints.sort ()

당신의 친구입니다. sort ()는 제자리에서 정렬되며 (실제로 기존 목록의 순서를 변경 함) 새 목록을 반환하지 않습니다.


이전 버전의 Python에서 ...

map(int,str(123))

새 버전 3k

list(map(int,str(123)))

(number/10**x)%10

루프에서 이것을 사용할 수 있습니다. 여기서 number는 전체 숫자이고 x는 루프 (0,1,2,3, ..., n)의 각 반복이며 n은 중지 지점입니다. x = 0은 1의 자리를, x = 1은 십을, x = 2는 수백을 나타냅니다. 이것은 오른쪽에서 왼쪽으로 숫자 값을 제공하므로 ISBN의 경우가 아닐 수 있지만 여전히 각 숫자를 분리합니다.


문자열로 변환하고 int () 함수를 사용하여 매핑합니다.

map(int, str(1231231231))

재귀 버전 :

def int_digits(n):
    return [n] if n<10 else int_digits(n/10)+[n%10]

로 변환하는 str것은 확실히 느리고 10으로 나눈 값입니다.

map 목록 이해력보다 약간 느립니다.

convert to string with map 2.13599181175
convert to string with list comprehension 1.92812991142
modulo, division, recursive 0.948769807816
modulo, division 0.699964046478

이 시간은 랩톱에서 다음 코드로 반환되었습니다.

foo = """\
def foo(limit):
    return sorted(set(map(sum, map(lambda x: map(int, list(str(x))), map(lambda x: x * 9, range(limit))))))

foo(%i)
"""

bar = """\
def bar(limit):
    return sorted(set([sum([int(i) for i in str(n)]) for n in [k *9 for k in range(limit)]]))

bar(%i)
"""

rac = """\
def digits(n):
    return [n] if n<10 else digits(n / 10)+[n %% 10]

def rabbit(limit):
    return sorted(set([sum(digits(n)) for n in [k *9 for k in range(limit)]]))

rabbit(%i)
"""

rab = """\
def sum_digits(number):
  result = 0
  while number:
    digit = number %% 10
    result += digit
    number /= 10
  return result

def rabbit(limit):
    return sorted(set([sum_digits(n) for n in [k *9 for k in range(limit)]]))

rabbit(%i)
"""


import timeit

print "convert to string with map", timeit.timeit(foo % 100, number=10000)
print "convert to string with list comprehension", timeit.timeit(bar % 100, number=10000)
print "modulo, division, recursive", timeit.timeit(rac % 100, number=10000)
print "modulo, division", timeit.timeit(rab % 100, number=10000)

이 루프의 본문을 사용하여 숫자로 원하는 작업을 수행하십시오.

for digit in map(int, str(my_number)):

이 프로그램을 만들었고 여기에 내 프로그램에서 실제로 체크 숫자를 계산하는 코드가 있습니다.

    #Get the 10 digit number
    number=input("Please enter ISBN number: ")

    #Explained below
    no11 = (((int(number[0])*11) + (int(number[1])*10) + (int(number[2])*9) + (int(number[3])*8) 
           + (int(number[4])*7) + (int(number[5])*6) + (int(number[6])*5) + (int(number[7])*4) +
           (int(number[8])*3) + (int(number[9])*2))/11)

    #Round to 1 dp
    no11 = round(no11, 1)

    #explained below
    no11 = str(no11).split(".")

    #get the remainder and check digit
    remainder = no11[1]
    no11 = (11 - int(remainder))

    #Calculate 11 digit ISBN
    print("Correct ISBN number is " + number + str(no11))

긴 코드 줄이지 만 한 줄의 코드에서 숫자를 분할하고 숫자에 적절한 양을 곱한 다음 함께 더한 다음 11로 나눕니다. .split () 함수는 목록 (소수점으로 분할 됨)을 생성하므로 목록의 두 번째 항목을 11에서 가져 와서 체크 숫자를 찾을 수 있습니다. 다음 두 줄을 변경하여 훨씬 더 효율적으로 만들 수도 있습니다.

    remainder = no11[1]
    no11 = (11 - int(remainder))

이에:

    no11 = (11 - int(no11[1]))

도움이 되었기를 바랍니다 :)


마찬가지로 DIGIS 반복하는 대답하지만, 더 많은 "파이썬"방법은 다음과 같습니다

while number:
    # "pop" the rightmost digit
    number, digit = divmod(number, 10)

한 줄로 된 숫자 목록은 어떻습니까?

ldigits = lambda n, l=[]: not n and l or l.insert(0,n%10) or ldigits(n/10,l)

답 : 165

방법 : 무차별 대입! 다음은 모든 것을 계산할 수있는 Python (버전 2.7) 코드입니다.

from math import sqrt, floor
is_ps = lambda x: floor(sqrt(x)) ** 2 == x
count = 0
for n in range(1002, 10000, 3):
    if n % 11 and is_ps(sum(map(int, str(n)))):
        count += 1
        print "#%i: %s" % (count, n)

Just assuming you want to get the i-th least significant digit from an integer number x, you can try:

(abs(x)%(10**i))/(10**(i-1))

I hope it helps.


After own diligent searches I found several solutions, where each has advantages and disadvantages. Use the most suitable for your task.

All examples tested with the CPython 3.5 on the operation system GNU/Linux Debian 8.


Using a recursion

Code

def get_digits_from_left_to_right(number, lst=None):
    """Return digits of an integer excluding the sign."""

    if lst is None:
        lst = list()

    number = abs(number)

    if number < 10:
        lst.append(number)
        return tuple(lst)

    get_digits_from_left_to_right(number // 10, lst)
    lst.append(number % 10)

    return tuple(lst)

Demo

In [121]: get_digits_from_left_to_right(-64517643246567536423)
Out[121]: (6, 4, 5, 1, 7, 6, 4, 3, 2, 4, 6, 5, 6, 7, 5, 3, 6, 4, 2, 3)

In [122]: get_digits_from_left_to_right(0)
Out[122]: (0,)

In [123]: get_digits_from_left_to_right(123012312312321312312312)
Out[123]: (1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 1, 3, 1, 2, 3, 1, 2, 3, 1, 2)

Using the function divmod

Code

def get_digits_from_right_to_left(number):
    """Return digits of an integer excluding the sign."""

    number = abs(number)

    if number < 10:
        return (number, )

    lst = list()

    while number:
        number, digit = divmod(number, 10)
        lst.insert(0, digit)

    return tuple(lst)

Demo

In [125]: get_digits_from_right_to_left(-3245214012321021213)
Out[125]: (3, 2, 4, 5, 2, 1, 4, 0, 1, 2, 3, 2, 1, 0, 2, 1, 2, 1, 3)

In [126]: get_digits_from_right_to_left(0)
Out[126]: (0,)

In [127]: get_digits_from_right_to_left(9999999999999999)
Out[127]: (9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9)

Using a construction tuple(map(int, str(abs(number)))

In [109]: tuple(map(int, str(abs(-123123123))))
Out[109]: (1, 2, 3, 1, 2, 3, 1, 2, 3)

In [110]: tuple(map(int, str(abs(1412421321312))))
Out[110]: (1, 4, 1, 2, 4, 2, 1, 3, 2, 1, 3, 1, 2)

In [111]: tuple(map(int, str(abs(0))))
Out[111]: (0,)

Using the function re.findall

In [112]: tuple(map(int, re.findall(r'\d', str(1321321312))))
Out[112]: (1, 3, 2, 1, 3, 2, 1, 3, 1, 2)

In [113]: tuple(map(int, re.findall(r'\d', str(-1321321312))))
Out[113]: (1, 3, 2, 1, 3, 2, 1, 3, 1, 2)

In [114]: tuple(map(int, re.findall(r'\d', str(0))))
Out[114]: (0,)

Using the module decimal

In [117]: decimal.Decimal(0).as_tuple().digits
Out[117]: (0,)

In [118]: decimal.Decimal(3441120391321).as_tuple().digits
Out[118]: (3, 4, 4, 1, 1, 2, 0, 3, 9, 1, 3, 2, 1)

In [119]: decimal.Decimal(-3441120391321).as_tuple().digits
Out[119]: (3, 4, 4, 1, 1, 2, 0, 3, 9, 1, 3, 2, 1)

ReferenceURL : https://stackoverflow.com/questions/974952/split-an-integer-into-digits-to-compute-an-isbn-checksum

반응형