Python 获取无穷多个索引的编号1121234…n

Python 获取无穷多个索引的编号1121234…n,python,python-3.x,algorithm,Python,Python 3.x,Algorithm,问:如果我们把这些数字块连接起来,我们会得到一个无限序列 从112123123412345123456开始。。。。名单是无限的 您将获得一个数字n,您的任务是返回位于的元素 序列中的索引,其中1≤ N≤ 10^18. 假设索引以 1,而不是0。例如: solve1=1,因为序列中的第一个字符是1。没有 索引0。 solve2=1,因为第二个字符也是1。 solve3=2,因为第三个字符是2 我的算法效率很低,我只是创建一个数字,直到达到索引n。这是codewars.com的一项任务 我想知道是否

问:如果我们把这些数字块连接起来,我们会得到一个无限序列 从112123123412345123456开始。。。。名单是无限的

您将获得一个数字n,您的任务是返回位于的元素 序列中的索引,其中1≤ N≤ 10^18. 假设索引以 1,而不是0。例如:

solve1=1,因为序列中的第一个字符是1。没有 索引0。 solve2=1,因为第二个字符也是1。 solve3=2,因为第三个字符是2

我的算法效率很低,我只是创建一个数字,直到达到索引n。这是codewars.com的一项任务

我想知道是否有人有更好的主意。 我的代码:

对于像99999999999999999这样的数字,它需要太多的时间来计算。 如果要测试:

print(solve(999999999999999999))

首先添加1位数字:112112123。。。在位置45处最多9个。这会让你在无限数中找到一个已知的位置。然后你加上两位数,你就可以计算出在无限数中加99的位置。对三位数字、四位数字重复上述步骤,以便您可以在无限数中设置一系列边界,已知起始点最多为10^18


给定n,找到给定n位于两个预先计算的边界之间的位置。从最近的边界向前或向后移动到n。

首先添加1位数字:1111112123。。。在位置45处最多9个。这会让你在无限数中找到一个已知的位置。然后你加上两位数,你就可以计算出在无限数中加99的位置。对三位数字、四位数字重复上述步骤,以便您可以在无限数中设置一系列边界,已知起始点最多为10^18


给定n,找到给定n位于两个预先计算的边界之间的位置。从最近的边界向前或向后搜索到n。

我们希望能够搜索三种类型的结构,1连接d位数字的序列,例如,单个数字:

123456...
或3位数字:

100101102103
2节中的行, 其中,每个节基于添加到前缀的前一节构建。例如,第1节:

1
12
123
...
或第3节:

1234...10111213...100
1234...10111213...100102
1234...10111213...100102103
<---- prefix ---->
完整的部分,尽管后者我们可以列举,因为它们呈指数增长,有助于构建我们的部分前缀。对于1,如果我们知道数字计数,我们可以使用简单除法;对于2,我们可以进行二进制搜索

下面的Python代码也回答了一些重要问题:

def getGreatestn,d,前缀: 行数=9*10**d-1 三角形=行*d+行*d//2 l=0 r=三角形 而l>1 三角形=中间*前缀+中间*d+中间*d//2 prevTriangle=mid-1*前缀+mid-1*d+mid-1*d//2 nextTriangle=mid+1*前缀+mid+1*d+mid+1*d//2 如果三角形>=n: 如果小于n: 返回三角形 其他: r=mid-1 其他: 如果nextTriangle>=n: 返回三角形 其他: l=中 返回l*前缀+l*d+l*d//2 def solven: 调试=1 d=0 p=0.1 前缀=[0] 章节=[0] 而第[d]我们希望能够搜索三种类型的结构,1连接d位数字的序列,例如,单个数字:

123456...
或3位数字:

100101102103
2节中的行, 其中,每个节基于添加到前缀的前一节构建。例如,第1节:

1
12
123
...
或第3节:

1234...10111213...100
1234...10111213...100102
1234...10111213...100102103
<---- prefix ---->
完整的部分,尽管后者我们可以列举,因为它们呈指数增长,有助于构建我们的部分前缀。对于1,如果我们知道数字计数,我们可以使用简单除法;对于2,我们可以进行二进制搜索

下面的Python代码也回答了一些重要问题:

def getGreatestn,d,前缀: 行=9 *10**d-1 三角形=行*d+行*d//2 l=0 r=三角形 而l>1 三角形=中间*前缀+中间*d+中间*d//2 prevTriangle=mid-1*前缀+mid-1*d+mid-1*d//2 nextTriangle=mid+1*前缀+mid+1*d+mid+1*d//2 如果三角形>=n: 如果小于n: 返回三角形 其他: r=mid-1 其他: 如果nextTriangle>=n: 返回三角形 其他: l=中 返回l*前缀+l*d+l*d//2 def solven: 调试=1 d=0 p=0.1 前缀=[0] 章节=[0] 而第[d]第一个想法是不需要实际字符串,只需要已经生成的假设字符串的长度,然后需要生成最后一个子字符串的给定元素

def solve(n):
  string=""
  i=1
  while len(string)<n:
    n-=len(string)
    string+=str(i)
    i+=1
  print("len:",len(string))
  return string[n-1]

print(solve(1))
print(solve(2))
print(solve(3))
print(solve(100))
print(solve(2100))
print(solve(31000))
#print(solve(999999999999999999))
#print(solve(1000000000000000000))
#print(solve(999999999999999993))
这一个将正确地为前6个测试生成1,1,2,1,2,2,并且还表明为了获得第31000个元素,它需要在内存中实际保留一个411字符串。这仍然不能扩展到超高变量,因此我们必须完全放弃生成字符串,并在内部使用相同的思想:跟踪长度,并从子字符串生成结果

我过一会儿回来。 这一个只有一个实际的字符串转换、偏移量,所有操作都是通过数学完成的,但它仍然不适用于较大的字符串:

from math import log10,floor

def solve(n):
  length=0
  i=1
  while length<n:
    n-=length
    length+=floor(log10(i))+1
    i+=1
  print("len:",length)
  i=1
  length=1
  while length<n:
    n-=length
    i+=1
    length=floor(log10(i))+1
  return str(i)[n-1]

print(solve(1))
print(solve(2))
print(solve(3))
print(solve(100))
print(solve(2100))
print(solve(31000))
#print(solve(999999999999999999))
#print(solve(1000000000000000000))
#print(solve(999999999999999993))

第一个想法是不需要实际字符串,只需要已经生成的假设字符串的长度,然后需要生成最后一个子字符串的给定元素

def solve(n):
  string=""
  i=1
  while len(string)<n:
    n-=len(string)
    string+=str(i)
    i+=1
  print("len:",len(string))
  return string[n-1]

print(solve(1))
print(solve(2))
print(solve(3))
print(solve(100))
print(solve(2100))
print(solve(31000))
#print(solve(999999999999999999))
#print(solve(1000000000000000000))
#print(solve(999999999999999993))
这一个将正确地为前6个测试生成1,1,2,1,2,2,并且还表明为了获得第31000个元素,它需要在内存中实际保留一个411字符串。这仍然不能扩展到超高变量,因此我们必须完全放弃生成字符串,并在内部使用相同的思想:跟踪长度,并从子字符串生成结果

我过一会儿回来。 这一个只有一个实际的字符串转换、偏移量,所有操作都是通过数学完成的,但它仍然不适用于较大的字符串:

from math import log10,floor

def solve(n):
  length=0
  i=1
  while length<n:
    n-=length
    length+=floor(log10(i))+1
    i+=1
  print("len:",length)
  i=1
  length=1
  while length<n:
    n-=length
    i+=1
    length=floor(log10(i))+1
  return str(i)[n-1]

print(solve(1))
print(solve(2))
print(solve(3))
print(solve(100))
print(solve(2100))
print(solve(31000))
#print(solve(999999999999999999))
#print(solve(1000000000000000000))
#print(solve(999999999999999993))

不知道这应该实现什么。第一个加速提示,不要使用字符串浓缩。将单个字符串放入一个列表中,并返回“`。如果需要相关字符串,请加入您的列表。好的,我发布了一个与确切任务相关的链接。我希望现在能更容易理解。现在不是时候。这是记忆。当r的长度为1000 PB减去1时,r[9999999999999-1]将存在。像PB。不知怎的,我怀疑你的机器里有那么多内存。你肯定需要一些其他的方法。不要发布链接。描述你想做什么。我不应该去其他网站去理解你的问题。实际上,我这样做是为了让我的帖子更容易阅读。不知道这应该实现什么。第一个加速提示,不要使用字符串浓缩。将单个字符串放入一个列表中,并返回“`。如果需要相关字符串,请加入您的列表。好的,我发布了一个与确切任务相关的链接。我希望现在能更容易理解。现在不是时候。这是记忆。当r的长度为1000 PB减去1时,r[9999999999999-1]将存在。像PB。不知怎的,我怀疑你的机器里有那么多内存。你肯定需要一些其他的方法。不要发布链接。描述你想做什么。我不应该去另一个网站去理解你的问题。实际上,我这样做是为了让我的帖子易于阅读。我认为,一旦你得到了两位数的数字,如果不进行修改,这是行不通的。例如,在123456789之后,序列继续12345678910,它有11个数字,而不是10个。已被修复。我认为,一旦得到两位数的数字,如果不进行修改,这是行不通的。例如,在123456789之后,序列继续12345678910
,它有11个数字,而不是10。已修复。一个例子回答了大问题。一个例子回答了大问题。