打印1到N - 数字计数

时间:2017-11-10 07:12:44

标签: python python-3.x

我正在编码网站上处理一个问题并且在解决它时遇到了一些问题。问题是:

  

打印1到N - 数字计数[ZOHO]

     

传递正整数N作为输入。如果我们打印所有的   数字从1到N连续,程序必须找到数字   字符(数字)C打印并打印计数C作为输出。

     

输入格式:第一行包含N。

     

输出格式:第一行包含C。

     

边界条件:1< = N< = 9999999

     

示例输入/输出1:输入:2

     

输出:2

     

说明:我们打印12,因此总字符数是   2。

     

示例输入/输出2:输入:15 ​​

     

输出:21

     

说明:我们打印123456789101112131415,因此总数   人物是21。

我解决了问题,但我的代码没有通过所有测试用例(它们被隐藏)。这是我的代码:

n = int(input())
assert 1<=n<=9999999
a = [str(i) for i in range(1,n+1)]
b = ''.join(a)
print(len(b))

这是解决问题的正确方法,还是有其他方法可以解决这个问题?

3 个答案:

答案 0 :(得分:2)

由于这是一个 Math 问题,我最好使用更多数学方法,因为它会使用更少的内存并且效率会更高。

这是我的方法。

  
      
  1. 计算数字的长度。

         
        
    • 如果length = 1,则保证您拥有9x1个字符。
    •   
    • 如果length = 2,则保证您拥有9x1 + 90x2个字符。
    •   
    • 如果length = 3,则保证您拥有9x1 + 90x2 + 900x3个字符,等等......
    •   
         

    我希望你能在这里看到循环

  2.   
  3. 对于其余部分,请举例12341234 - 1000 = 234数字 length =数字的长度。不,错误:234   +1 = 235个数字 length =数字的长度

  4.   

在代码中制定它。

n = input()
length = len(n)
x,s = 9,0
for i in range(1,length):
    s=s+x*i
    x = x*10 # 9-> 90-> 900->
print(s+(int(n)-10**(length-1)+1)*length) # 234 + 1
#         1234 - 10^3
#            = 234            +1
#                          = 235 * 4(length) = ...
>>> 1234
3829
>>>> 15
21

我也import time看到了效率。对于n=9999999,您的代码大约需要 3.26秒,而此代码需要 160-200 usec

答案 1 :(得分:1)

这里的版本使用与Miraj50的答案基本相同的算法,除了它不需要循环来计算数字长度比当前输入数字少的数字。我在这个OEIS条目的帮助下开发了我的公式:A033713&#34;数字1到999..9(n位)&#34;中的零数。

我将添加一个稍微修改过的Miraj50代码版本,以及Blender评论中给出的暴力版本,以表明它们都给出了相同的结果。

public func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
    guard let applicationBundleId = options[UIApplicationOpenURLOptionsKey.sourceApplication] as? String else {
        return true
    }

    // Save your source application
    sourceApplicationBundleId = applicationBundleId
    return true
}

var sourceApplicationBundleId: String?

// Attempt to open application from which your app was opened
func openApplication() {
    guard let applicationBundleId = sourceApplicationBundleId, let url = url(for: applicationBundleId) else {
        return
    }
    UIApplication.shared.open(url, options: [:], completionHandler: nil)
}

func url(for bundleId: String) -> URL? {
    guard let scheme = knownUrlSchemes[bundleId] else {
        return nil
    }

    return URL(string: scheme)!
}

// A list of known url schemes
var knownUrlSchemes: Dictionary<String, String> = {
    return ["com.google.Maps": "comgooglemaps://",
            "com.facebook.Facebook": "fb://"]
}()

<强>输出

def nlen_blender(n):
    return sum(len(str(i)) for i in range(1,n+1))

def nlen_miraj(n):
    length = len(str(n))
    x, s = 9, 0
    for i in range(1,length):
        s = s + x*i
        x = x*10 
    return s + (n - 10**(length-1) + 1) * length

def nlen_pm2r(n):
    digits = len(str(n))
    a = 10 ** (digits - 1) 
    return (n + 1) * digits - a - (a - 1) // 9

# test

funcs = (nlen_blender, nlen_miraj, nlen_pm2r)
data = (0, 1, 37, 563, 4285, 12900, 375462)
for n in data:
    print(n)
    for f in funcs:
        print('{:13}: {}'.format(f.__name__, f(n)))
    print()

n = 12398765434324
print(n)
for f in (nlen_miraj, nlen_pm2r):
    print(f(n))

这是一个进行0 nlen_blender : 0 nlen_miraj : 0 nlen_pm2r : 0 1 nlen_blender : 1 nlen_miraj : 1 nlen_pm2r : 1 37 nlen_blender : 65 nlen_miraj : 65 nlen_pm2r : 65 563 nlen_blender : 1581 nlen_miraj : 1581 nlen_pm2r : 1581 4285 nlen_blender : 16033 nlen_miraj : 16033 nlen_pm2r : 16033 12900 nlen_blender : 53394 nlen_miraj : 53394 nlen_pm2r : 53394 375462 nlen_blender : 2141667 nlen_miraj : 2141667 nlen_pm2r : 2141667 12398765434324 162471604969439 162471604969439 测试的版本。正如您所看到的,消除timeit循环会加快速度,尤其是当for很大时。

n

<强>输出

from timeit import Timer

def nlen_miraj(n):
    length = len(str(n))
    x, s = 9, 0
    for i in range(1,length):
        s = s + x*i
        x = x*10 
    return s + (n - 10**(length-1) + 1) * length

def nlen_pm2r(n):
    digits = len(str(n))
    a = 10 ** (digits - 1) 
    return (n + 1) * digits - a - (a - 1) // 9

def time_test(num, loops):
    timings = []
    for func in funcs:
        t = Timer(lambda: func(num))
        result = sorted(t.repeat(3, loops))
        timings.append((result, func.__name__))
    timings.sort()
    for result, name in timings:
        print('{:13} : {}'.format(name, result))
    print()

funcs = (nlen_miraj, nlen_pm2r)
data = (0, 1, 37, 563, 4285, 12900, 375462, 12398765434324)

loops = 10000
for n in data:
    print(n)
    time_test(n, loops)

这些时间是在我在Debian衍生Linux上运行Python 3.6.0的旧2GHz 32位机器上获得的。

答案 2 :(得分:0)

我发现了两种新的方法,第一种方法使用类似于Miraj50的方法(我在发布它的时候,因为为了完整性而将它保留在这里),以for循环的方式而第二个使用向量代数来计算它,它也可以在numpy中实现,这可以改善其对大数字的性能。您可以在以下部分中将它们视为方法ab

分析脚本

我用以下脚本做了一些时间安排。随意修改INPUTSREPETITIONS。它需要一段时间,因为它正在执行REPETITIONS * len(INPUTS)次每个方法,len(INPUTS)倍OP的方法来验证结果。它计算样本的均值,中位数和标准差,并以漂亮的表格格式打印出来。如果要添加新方法,只需定义函数并将其包含在methods字典中。

# Values to test
INPUTS = [7, 9, 53, 99, 999, 9999, 99999, 999999, 9999999]
# Number of repetitions
REPETITIONS = 30000

from timeit import default_timer as timer

def a(n): # Iterative method
    #n = input("Insert a number: ")
    start = timer()
    l = len(n)
    if l == 1: # Special case as int("9"*0) raises ValueError
        c = int(n)
    else:
        n, c = int(n), 9
        for i in range(2, n+1):
            if l == i:
                c += (n - int("9"*(i-1))) * i
                break
            c += int("9"+ "0"*(i-1)) * i
    print(c)
    end = timer()
    return c, end - start

def b(n): # No-loop method
    #n = input("Insert a number: ")
    start = timer()
    l = len(n)
    n = int(n)
    aux = [9*10**i for i in range(l-1)]
    aux.append(n - sum(aux))
    c = sum((v*(i+1) for i, v in enumerate(aux)))
    print(c)
    end = timer()
    return c, end - start

def c(n): # Miraj50's method
    #n = input("Insert a number: ")
    start = timer()
    l = len(n)
    x, c = 9, 0
    for i in range(1, l):
        c = c + x*i
        x = x * 10
    c = c + (int(n) - 10**(l-1) + 1) * l
    print(c)
    end = timer()
    return c, end - start

def d(n): # Pm2 Ring's method
    #n = input("Insert a number: ")
    start = timer()
    l = len(n)
    a = 10 ** (l - 1) 
    c = (int(n) + 1) * l - a - (a - 1) // 9
    print(c)
    end = timer()
    return c, end - start


# Method mapper
methods = {
           'Adirio 1': a,
           'Adirio 2': b,
           'Miraj50' : c,
           'PM2 Ring': d,
          }
methods_list = sorted(methods.keys())

# Calculate the results that are valid
results = []
for n in INPUTS:
    results.append(len(''.join(str(i) for i in range(1, n+1))))

# Calculate the results by the different methods
times = {}
for n, result in zip(INPUTS, results):
    t = {} # Store times
    for key in methods:
        aux1 = []
        for i in range(REPETITIONS):
            c, aux2 = methods[key](str(n))
            if c != result:
                raise ValueError("Method {} for n = {} yielded {} and {} was expected".format(key.upper(), n, c, result))
            aux1.append(aux2)
        aux1.sort()
        mean = sum(aux1) / REPETITIONS
        if REPETITIONS % 2 == 0:
            median = (aux1[REPETITIONS//2 - 1] + aux1[REPETITIONS//2]) / 2
        else:
            median = aux1[(REPETITIONS-1)//2]
        std_dev = (sum((x-mean)**2 for x in aux1)/(REPETITIONS-1))**.5
        t[key] = {
            'mean': mean,
            'median': median,
            'std_dev': std_dev,
            'min': aux1[0],
            'max': aux1[-1],
        }
    times[n] = t

# Print the results
for n, c in zip(INPUTS, results):
    print()
    print("N = {:<15}".format(n), end='')
    for method in methods_list:
        print("|{:^19}".format("Method {}".format(method)), end='')
    print()
    print("+".join(["-"*19]*(len(methods_list)+1)))
    for metric in times[INPUTS[0]][methods_list[0]]:
        print(" {:<12} [us] ".format(metric), end='')
        for method in methods_list:
            print("| {:>17.2f} ".format(times[n][method][metric] *10**6), end='')
        print()

结果

 N = 7             |  Method Adirio 1  |  Method Adirio 2  |  Method Miraj50   |  Method PM2 Ring  
-------------------+-------------------+-------------------+-------------------+-------------------
 median       [us] |             12.76 |             14.95 |             13.49 |             13.13 
 min          [us] |             10.21 |             12.03 |             10.94 |             10.57 
 mean         [us] |             85.15 |             87.11 |             83.93 |             85.68 
 max          [us] |          35319.77 |          37254.20 |          35428.07 |          35010.91 
 std_dev      [us] |           1486.21 |           1480.59 |           1465.55 |           1483.09 

 N = 9             |  Method Adirio 1  |  Method Adirio 2  |  Method Miraj50   |  Method PM2 Ring  
-------------------+-------------------+-------------------+-------------------+-------------------
 median       [us] |             12.76 |             14.95 |             13.49 |             13.13 
 min          [us] |             10.21 |             12.03 |             10.57 |             10.21 
 mean         [us] |             84.94 |             87.42 |             86.09 |             85.72 
 max          [us] |          34595.95 |          35712.49 |          36281.33 |          36368.85 
 std_dev      [us] |           1485.61 |           1486.80 |           1489.28 |           1482.85 

 N = 53            |  Method Adirio 1  |  Method Adirio 2  |  Method Miraj50   |  Method PM2 Ring  
-------------------+-------------------+-------------------+-------------------+-------------------
 median       [us] |             13.86 |             15.32 |             13.86 |             13.49 
 min          [us] |             10.94 |             12.03 |             10.94 |             10.94 
 mean         [us] |             85.93 |             88.38 |             85.41 |             85.91 
 max          [us] |          34776.45 |          38539.21 |          36581.07 |          36074.94 
 std_dev      [us] |           1477.20 |           1489.63 |           1477.41 |           1485.53 

 N = 99            |  Method Adirio 1  |  Method Adirio 2  |  Method Miraj50   |  Method PM2 Ring  
-------------------+-------------------+-------------------+-------------------+-------------------
 median       [us] |             14.22 |             15.32 |             13.86 |             13.49 
 min          [us] |             10.94 |             12.76 |             10.94 |             10.94 
 mean         [us] |             88.21 |             88.46 |             86.46 |             87.04 
 max          [us] |          40802.19 |          35949.14 |          36355.72 |          39536.51 
 std_dev      [us] |           1518.92 |           1489.06 |           1488.02 |           1525.52 

 N = 999           |  Method Adirio 1  |  Method Adirio 2  |  Method Miraj50   |  Method PM2 Ring  
-------------------+-------------------+-------------------+-------------------+-------------------
 median       [us] |             14.59 |             16.04 |             14.22 |             13.49 
 min          [us] |             12.03 |             13.13 |             11.30 |             10.57 
 mean         [us] |             87.68 |             88.48 |             86.96 |             85.81 
 max          [us] |          35570.64 |          36136.57 |          42908.73 |          36164.28 
 std_dev      [us] |           1488.79 |           1482.06 |           1489.39 |           1481.22 

 N = 9999          |  Method Adirio 1  |  Method Adirio 2  |  Method Miraj50   |  Method PM2 Ring  
-------------------+-------------------+-------------------+-------------------+-------------------
 median       [us] |             15.32 |             16.41 |             14.22 |             13.49 
 min          [us] |             12.40 |             13.49 |             11.67 |             10.57 
 mean         [us] |             88.06 |             88.91 |             86.78 |             85.58 
 max          [us] |          34688.20 |          34618.92 |          35010.55 |          40569.91 
 std_dev      [us] |           1478.79 |           1473.64 |           1495.85 |           1480.70 

 N = 99999         |  Method Adirio 1  |  Method Adirio 2  |  Method Miraj50   |  Method PM2 Ring  
-------------------+-------------------+-------------------+-------------------+-------------------
 median       [us] |             16.04 |             17.14 |             14.59 |             13.49 
 min          [us] |             13.13 |             14.22 |             11.67 |             10.94 
 mean         [us] |             89.44 |             89.79 |             88.20 |             86.94 
 max          [us] |          44273.23 |          42208.25 |          40763.54 |          37936.45 
 std_dev      [us] |           1497.36 |           1482.44 |           1512.71 |           1495.37 

 N = 999999        |  Method Adirio 1  |  Method Adirio 2  |  Method Miraj50   |  Method PM2 Ring  
-------------------+-------------------+-------------------+-------------------+-------------------
 median       [us] |             16.41 |             17.50 |             14.59 |             13.49 
 min          [us] |             13.86 |             14.59 |             12.03 |             10.94 
 mean         [us] |             88.60 |             90.63 |             87.18 |             85.68 
 max          [us] |          35199.80 |          36482.62 |          48330.99 |          51652.53 
 std_dev      [us] |           1475.87 |           1485.87 |           1483.34 |           1491.72 

 N = 9999999       |  Method Adirio 1  |  Method Adirio 2  |  Method Miraj50   |  Method PM2 Ring  
-------------------+-------------------+-------------------+-------------------+-------------------
 median       [us] |             17.14 |             17.87 |             14.95 |             13.86 
 min          [us] |             14.22 |             15.32 |             12.40 |             11.30 
 mean         [us] |             89.97 |             89.86 |             87.74 |             85.51 
 max          [us] |          35618.05 |          35605.65 |          36453.44 |          34081.07 
 std_dev      [us] |           1480.06 |           1467.89 |           1488.62 |           1475.57

解释结果

在制表的5项措施中,您需要了解一些影响。由于OS的调度程序可能在算法中间执行不同的进程,因此某些时序具有相当大的错误,它们占用了他们真正需要的太多时间。这意味着max,或者考虑样本中所有值的均值和标准差给出的上限给出了不值得信赖的结果。最小值和中值都以不同的方式消除了这个真正长期的情况。基于中值和最小值的算法比较非常相似:所有算法都有类似的执行时间,@ PM2Ring版本稍快一些。