- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个整数列表,它在循环中不断修改,我需要判断它的内容在一定数量的迭代后是否会重复以打破循环。
如果没有,列表
最终将修改为[]
,或者当达到一定的迭代限制时循环终止。到目前为止我的解决方案:
def modify(numlist, a, b):
numlist = [(x * a) for x in numlist]
for i in range((len(numlist) - 1), 0, -1):
if numlist[i] >= b: numlist[i - 1] += numlist[i] // b
numlist[i] = numlist[i] % b
numlist[0] %= b
while numlist[-1] == 0:
numlist.pop(-1)
if numlist == []: break
numlist = [1, 2, 3, 4, 5]
listHistory = [numlist]
a, b = someValue, anotherValue
n = 0
while numlist != [] and n <= limit:
modify(numlist, int(a), int(b))
listHistory.append(numlist)
if numlist in listHistory: break
n += 1
limit
可以非常大(大约 10**6
- 10**7
)并检查当前的 numlist
相对于所有以前的版本来说变得非常慢。
有没有更有效的方法来做到这一点,甚至有一种方法可以通过列表初始内容和给定的a
、b
来预先确定修改是否是周期性的?
最佳答案
好的,有东西了。如果您查看列表中的最后一个元素,我们将其称为 m
。发生了什么,它会乘以 a,然后对 b 取模。它永远不会与任何其他元素混合,因此如果列表的配置必须重复自身,则必须保留以下内容:
m*a^n=m modulo b
<==>a^n=1 modulo b
< >a^(n+1)=a modulo b
这是一个你可以利用 Fermats little theorem 的问题如果 a 和 b 互质,则
a^phi(b)=1 modulo b
其中phi
是Eulers totient函数。
因此,这会大大减少您必须存储在历史记录中的列表配置的数量。您只需在每个 phi(b)
步骤中存储它即可。
我在这里找到了 phi 的实现: Computing Eulers Totient Function
更新:
好的,如果您要执行 += list[i] % b
而不是 += list[i]//b
,我找到了一个快速解决方案。否则,在最坏的情况下您需要 b^4*phi(b)
步骤
更新2:
我用C
重写了代码(见下文)以使其更快,并实现了@user2357112提出的“龟兔赛跑”算法。这样我可以每秒检查几百万个循环,这应该比 python 实现快得多。我尝试了一些不同的值组合:
a b steps b^4*phi(b) (b/GCD(b,a))^4*phi(b/GCD(n,a)) (b/GCD(b,a))^4*phi(b/GCD(n,a))/steps
2 37 67469796 67469796 67469796 1
3 37 33734898 67469796 67469796 2
4 37 33734898 67469796 67469796 2
5 37 67469796 67469796 67469796 1
6 37 7496644 67469796 67469796 9
7 37 16867449 67469796 67469796 4
36 37 3748322 67469796 67469796 18
2 36 39366 20155392 629856 16
3 36 256 20155392 82944 27648
4 36 19683 20155392 39366 2
5 36 5038848 20155392 20155392 4
所以你知道这是怎么回事了:循环长度似乎总是(b/GCD(b,a))^4*phi(b/GCD(n,a))的除数
,所以最坏的情况是怀疑的 (b/GCD(b,a))^4*phi(b/GCD(n,a))
步骤
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void modify(int *, int, int);
void printl(int * );
int main(int argc, const char*argv[])
{
int l[5]={1,2,3,4,5};
int lz[5]={1,2,3,4,5};
int i=1,a,b,n;
if (argc<4) {
printf("Not enough arguments!!\n");
exit(1);
}
a=atoi(argv[1]);
b=atoi(argv[2]);
n=atoi(argv[3]);
modify(l,a,b);
while (i<n) {
modify(l,a,b);
modify(l,a,b);
modify(lz,a,b);
i++;
if (memcmp(l,lz,sizeof(l))==0) {
printf("success!\n");
break;
}
if (i%1000000==0) printf("Step %d.000.000\n",i/1000000);
}
printf("Final step: %d\n",i);
printl(l);
printl(lz);
return 0;
}
void modify(int * li, int a, int b) {
int i=0;
while (i<=4) {
li[i]*=a;
i++;
}
i=4;
while (i>=1) {
if (li[i]>=b) {
li[i-1]+=li[i]/b;
}
li[i]=li[i]%b;
i--;
}
li[0]=li[0]%b;
}
void printl(int * li) {
printf("l=(%d,%d,%d,%d,%d)\n",li[0],li[1],li[2],li[3],li[4]);
关于python - 测试列表修改是否是周期性的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22520344/
如标题所示,ans_list是一个答案列表,ans_index是一个数字(答案在词汇表中的索引,但与atm无关) 这里生成的 tree.anslist 是什么? (例如,仅针对第一个),忽略迭代。 f
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我目前将用户的输入存储在逗号分隔的列表中,如下所示: Userid | Options 1 | 1,2,5 用户在一个数组形式中勾选一组选项,然后用逗号连接起来 1,2,5 然后 MySQ
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将具有一个元素的东西拿走。 这与 How do I “flatte
我想知道如何完全展平列表和包含它们的东西。除其他外,我想出了一个解决方案,它可以将具有多个元素的东西滑倒并将它们放回原处,或者在滑倒后将带有一个元素的东西拿走。 这与 How do I “flatte
这个问题已经有答案了: Convert nested list to 2d array (3 个回答) 已关闭 7 年前。 java中有没有快捷方式可以转换 List> 到 String[][] ?
我在排序时遇到问题 List> 。我创建了一个自定义比较器,在其中编写了对数据进行排序的代码。 public class CustomComparator implements Comparator
这个问题已经有答案了: 已关闭10 年前。 Possible Duplicate: Java Generics: Cannot cast List to List? 我只是想知道为什么下面的java代
试图想出一个 LINQy 方法来做到这一点,但我什么也没想到。 我有一个对象列表<>,其中包含一个属性,该属性是逗号分隔的字母代码列表: lst[0].codes = "AA,BB,DD" lst[1
假设我有这些任务: points = [] point = (1, 2) 我怎么会这样做: points += point 它工作得很好,并且给了我点 = [1, 2]。但是,如果我这样做: poin
如何在 scala 中将 List[Task[List[Header]]] 类型转换为 Task[List[Header]]。 我有一个方法返回 Task[List[Header]] 并多次调用 do
如何在 Java 中查找二维列表的元素? 我有一个参数为 List> 的函数我想知道如何找到这个列表的行和列。 最佳答案 如果你喜欢 List> obj 然后你就可以像这样访问 obj.get(cur
分配 List到 List工作正常。 分配 List>到 List>不编译。 代码 public class Main { public static void main(String[] a
我正在用 Java 编写一个方法,该方法必须接收并迭代 Serializable 的 List。 有什么区别: public void myMethod(List list) { } 和 public
我看到很多人想用 mvvm 更新网格/列表/树的一部分,但他们不想刷新整个列表。 对于所有遇到此问题的人,我做了以下示例。 希望这对你有用。 最佳答案 这是一个简单的例子。整个代码中最重要的是: Bi
我正在为现有的 C++ 库编写包装器,该库使用列表,其中 T 是自定义结构。我被建议使用 vector 而不是列表,但我试图避免修改库。 为了更好地理解这个场景,我做了一个简单的应用程序,使用一个列表
List list List list 这两种声明有什么区别吗? 谢谢, 最佳答案 是的。 List可以包含所有派生自 Base 的不同事物的混合物. List包含同质项(从某种意义上说,它们必须全部
有人可以尽可能详细地解释以下类型之间的区别吗? List List List 让我更具体一点。我什么时候想使用 // 1 public void CanYouGiveMeAnAnswer(List l
我有一个元组列表,每个元组都是一对列表。所以我的数据看起来像: mylist = [(['foo', 'bar'], ['bar', 'bar']),(['bar', 'bar'],['bar', '
也许是一个时髦的标题,但我遇到了以下问题: 给定一个类型为 (a * b) list 的列表,我想创建一个类型为 (a * b list) list 的新列表。一个例子: 给定列表 let testL
我是一名优秀的程序员,十分优秀!