2020-09-13: ¿Cómo determinar si un número entero positivo es a elevado a la potencia de b, a y b son números enteros y mayores o iguales que 2, cómo resolverlo?

Fu Ge respuesta 2020-09-13:

Primero determine el rango de b, el rango de b debe estar en [2, logN]. Luego, recorra b para encontrar el rango de a. Si la longitud del rango es igual a 0, significa que el entero positivo es a elevado a b.
1. Atraviese el rango b. Encuentre a por dicotomía. El rango inicial de a es [2, logN]. 2 elevado a 400 toma 5 segundos. [Con código]
2. Recorre el rango de b. Optimice la dicotomía para encontrar a, el rango inicial de a es [2, el resultado de la a anterior]. 2 elevado a 10,000 toma 5 segundos. [Hay código]
3. Debería haber una solución más optimizada, pero no la esperaba por el momento. 【Sin código】

Debido a que se usan números enteros grandes, están escritos en Python. el código se muestra a continuación:

#!/usr/bin/python3
import time
from functools import wraps
def _get_sqrt_range(num, right, exp=2):
    """
        求num的exp开方,exp是指数,num是结果。求底数。
        Args:
            num: 大于等于0并且是整数。
            right: 大于等于0并且是整数。右边界。
            exp: 大于等于0并且是整数。
        Returns:
            返回元组,表示一个开方范围。
        Raises:
            IOError: 无错误。
    """
    left = 1
    if num == 0:
        return 0, 0
    if num == 1:
        return 1, 1
    if num == 2 or num == 3:
        return 1, 2
    while True:
        mid = (left + right) // 2
        if mid ** exp > num:
            right = mid
            if left ** exp == num:
                return left, left
            if left + 1 == right:
                return left, right
        elif mid ** exp < num:
            left = mid
            if right ** exp == num:
                return right, right
            if left + 1 == right:
                return left, right
            if mid == 1:
                return 1, 2
        else:
            return mid, mid


def get_log_range(num, basenum):
    """
        求对数范围。
        Args:
            num: 数,大于等于1并且是整数。
            basenum: 底数,大于等于2并且是整数。
        Returns:
            返回结果。对数范围。
        Raises:
            IOError: 无错误。
    """
    if num == 1:
        return 0, 0
    else:
        n = 0
        ism = 0
        while num >= basenum:
            if ism == 0 and num % basenum != 0:
                ism = 1
            n += 1
            num //= basenum
        return n, n + ism

def timefn(fn):
    """计算性能的修饰器"""
    @wraps(fn)
    def measure_time(*args, **kwargs):
        t1 = time.time()
        result = fn(*args, **kwargs)
        t2 = time.time()
        print(f"@timefn: {fn.__name__} took {t2 - t1: .5f} s")
        return result
    return measure_time

@timefn
def is_power1(num):
    """
        判断n是否是一个数的幂次方形式。
        Args:
            num: 大于等于0并且是整数。
        Returns:
            返回结果。true是幂数
        Raises:
            IOError: 无错误。
    """
    if num <= 3:
        return False
    else:
        log_range = get_log_range(num, 2)
        if log_range[0] == log_range[1]:
            return True
        expmax = log_range[0]
        expmin = 2
        exp = expmin
        sqrt = 0
        right = 2 ** (1 + log_range[0] // 2)
        while exp <= expmax:
            sqrt = _get_sqrt_range(num, right, exp)
            # right = sqrt[0]#缩小右边界范围
            if sqrt[0] == sqrt[1]:
                return True
            if sqrt == (1, 2):
                return False
            exp += 1
        return False

@timefn
def is_power2(num):
    """
        判断n是否是一个数的幂次方形式。
        Args:
            num: 大于等于0并且是整数。
        Returns:
            返回结果。true是幂数
        Raises:
            IOError: 无错误。
    """
    if num <= 3:
        return False
    else:
        log_range = get_log_range(num, 2)
        if log_range[0] == log_range[1]:
            return True
        expmax = log_range[0]
        expmin = 2
        exp = expmin
        sqrt = 0
        right = 2 ** (1 + log_range[0] // 2)
        while exp <= expmax:
            sqrt = _get_sqrt_range(num, right, exp)
            right = sqrt[0]  # 缩小右边界范围
            if sqrt[0] == sqrt[1]:
                return True
            if sqrt == (1, 2):
                return False
            exp += 1
        return False


if __name__ == "__main__":
    print("----2的400次方")
    num = 2 ** 400 + 1
    print(is_power1(num))
    print(is_power2(num))
    print("\r\n----2的10000次方")
    num = 2 ** 10000 + 1
    print(is_power2(num))

Los resultados de ejecutar el código son los siguientes:
Inserte la descripción de la imagen aquí


comentario

Supongo que te gusta

Origin blog.csdn.net/weixin_48502062/article/details/108568277
Recomendado
Clasificación