旋转“是通过将字符串分成两部分并颠倒其顺序进行的”。如果对象在应用操作之后未更改,则该对象在操作下是对称的。因此,“旋转对称”是字符串在“旋转”之后保持不变的事实。
给定一个非空字符串,该字符串s
仅包含从a
到的字母z
,输出该字符串旋转对称性的最高顺序。
测试用例:
input output
a 1
abcd 1
abab 2
dfdfdfdfdfdf 6
旋转“是通过将字符串分成两部分并颠倒其顺序进行的”。如果对象在应用操作之后未更改,则该对象在操作下是对称的。因此,“旋转对称”是字符串在“旋转”之后保持不变的事实。
给定一个非空字符串,该字符串s
仅包含从a
到的字母z
,输出该字符串旋转对称性的最高顺序。
测试用例:
input output
a 1
abcd 1
abab 2
dfdfdfdfdfdf 6
Answers:
lambda s:len(s)/(s+s).find(s,1)
找到s
in 的第一个非零索引,s+s
找出我们必须旋转多远才能s
返回,然后将in 的长度s
除以该数字。基于我在其他地方看到的想法。
A+B:-findall(X,(append(X,Y,A),append(Y,X,A)),[_|Z]),length(Z,B).
定义一个谓词+/2
,该谓词将字符串(以字符代码列表的形式)作为其第一个参数(A
),并将其第二个参数(B
)设置为最高阶对称旋转的顺序。
该程序使用以下事实:字符串上的一组对称旋转是一个循环组,因此,一组对称旋转的顺序等于最高阶对称旋转的顺序。因此,程序可以通过找到输入字符串上对称旋转的总数来计算所需的结果。
大部分繁重的工作都是通过调用findall/3
谓词来完成的。所述findall/3
谓词认定为第一个参数(所有不同的可能的值X
在这种情况下),使得给定的作为第二个参数的表达式为真((append(X,Y,A),append(Y,X,A))
,稍后更多)。最后,它将这些可能的值中的每一个X
作为最终值存储在列表中([_|Z]
)中。
传递到表达式findall/3
作为第二arugment,(append(X,Y,A),append(Y,X,A))
使用append/3
谓词来指定X
一些尚未定义的级联Y
必须等于A
,输入字符串,和在相同Y
级联与X
也必须等于A
。这意味着X
必须是A
这样的前缀,如果将其从的前面删除A
并添加到后面,则结果字符串与相同A
。X
具有此属性的s 集与的对称旋转几乎一一对应A
。总是存在一种重复计数的情况,这是由于空字符串和A
都是前缀A
对应于的0旋转A
。由于的0
-rotation A
始终是对称的,因此X
s from 的结果列表的长度findall/3
将比上的对称旋转的数量大1 A
。
为了解决重复计数问题,我在findall/3
谓词的第三个参数上使用了模式匹配。在Prolog中,列表以其头部(第一个元素)和尾部(其余元素)成对表示。因此,[_|Z]
表示一个列表,其尾部等于Z
。这意味着的长度Z
比findall/3
谓词找到的前缀数少一个,因此等于的对称旋转数A
。最后,我使用length/2
谓词B
将长度设置为Z
。
¬x@¥UéY
¬ x@ ¥ UéY
q xXY{ ==UéY} // Expanded
Uq xXY{U==UéY} // Variable introduction
// Implicit: U = input string
Uq // Split U into chars.
xXY{ } // Map each item X and index Y by this function, then sum the results:
U==UéY // Return U equals (U rotated by Y characters).
// Implicit: output result of last expression
g x=sum[1|a<-[1..length x],drop a x++take a x==x]
g x=sum[1|(a,_)<-zip[1..]x,drop a x++take a x==x]
这使用了指出的简单解决方案@ 0'。由于字符串的旋转形成一个循环组,因此最高阶元素与该组的大小相同,因此我们可以通过找到对称旋转数来获得单位的阶数。
简单的代码执行列表理解并计算保留原始字符串的转数。
(<>)
在我使用的Haskell版本中,@ BMO 并不是序幕。