提问人:Chi-fung LAM 提问时间:10/12/2023 最后编辑:Chi-fung LAM 更新时间:10/18/2023 访问量:61
用于检测和分解算术或几何序列的算法
algorithms to detect and break down arithmetic or geometric sequence
问:
如果一个序列是纯算术或纯几何,它很容易被检测。(1,3,5,7,9...)
(3,9,27,81...)
“混合”算术/几何序列怎么样?
e.g. 2 3 5 6 7 9 10 14
it contain 3 arithmetic sequences (3 6 9), (3 5 7 9) and (2 6 10 14) in it.
e.g. 2 3 4 8 9 16 27 32 81
it contain 2 geometric sequences (2 4 8 16 32) and (3 9 27 81) in it.
e.g. 2 3 4 5 8 9 16 32
it contain 1 geometric sequence (2 4 8 16 32) and 2 arithmetic sequences (2 3 4 5) (3 5 7 9) in it.
(假设序列应包含 2 个以上的元素)
有没有算法可以检测(分析)上述混合序列并对其进行分解?即检测并列出其中的所有序列?(假设原始序列包含整数)<= 20
谢谢。
问候
林志峰
基于 Abhinav Mathur 算法的代码,可能需要更多的调试,所有结果都是 -1 ;<
#include <Array.au3>
Func GetSequences(ByRef $arr)
Local $arithmetic_seq[1], $geometric_seq[1]
Local $n = UBound($arr)
For $i = 0 To $n - 3
For $j = $i + 1 To $n - 2
Local $arithmetic = $arr[$i] & "|" & $arr[$j]
Local $geometric = $arr[$i] & "|" & $arr[$j]
Local $d = $arr[$j] - $arr[$i]
Local $r = $arr[$j] / $arr[$i]
$ArithTmp=$arr[$j]
$GeoTmp=$arr[$j]
For $k = $j + 1 To $n - 1
If ($arr[$k] - $ArithTmp) = $d Then
$arithmetic &= "|" & $arr[$k]
$ArithTmp=$arr[$k]
EndIf
If $arr[$k] / $GeoTmp = $r Then
$geometric &= "|" & $arr[$k]
$GeoTmp=$arr[$k]
EndIf
Next
If StringReplace($arithmetic, "|", "") <> $arr[$i] & $arr[$j] And StringLen($arithmetic) > 2 Then
_ArrayAdd($arithmetic_seq, StringSplit($arithmetic, "|", 2))
EndIf
If StringReplace($geometric, "|", "") <> $arr[$i] & $arr[$j] And StringLen($geometric) > 2 Then
_ArrayAdd($geometric_seq, StringSplit($geometric, "|", 2))
EndIf
Next
Next
ConsoleWrite("Sequences for " & _ArrayToString($arr) & @CRLF)
ConsoleWrite("Arithmetic: " & @CRLF)
_ArrayDisplay($arithmetic_seq)
; Clear the arithmetic sequence for the next iteration
_ArrayDelete($arithmetic_seq, 1)
ConsoleWrite("Geometric: " & @CRLF)
_ArrayDisplay($geometric_seq)
; Clear the geometric sequence for the next iteration
_ArrayDelete($geometric_seq, 1)
EndFunc
Local $sequence1[9] = [2, 3, 5, 6, 7, 8, 9, 10, 14]
Local $sequence2[9] = [2, 3, 4, 8, 9, 16, 27, 32, 81]
Local $sequence3[9] = [2, 3, 4, 5, 7, 8, 9, 16, 32]
Local $sequences[3] = [$sequence1, $sequence2, $sequence3]
For $i = 0 To UBound($sequences) - 1
GetSequences($sequences[$i])
Next
答:
1赞
Abhinav Mathur
10/12/2023
#1
由于原始序列有 ,因此更容易对其进行暴力破解。为此,您可以使用一个简单的算法:N<=20
l, n = your_input_list, number_of_elements
arithmetic_seq, geometric_seq = [], []
for i in [1, n]:
for j in [i+1, n]:
arithmetic, geometric = [l[i], l[j]], [l[i], l[j]]
d = l[j] - l[i]
r = l[j] / l[i]
while (arithmetic[-1] + d) in l:
arithmetic.append(arithmetic[-1] + d)
while (geometric[-1] * r) in l:
geometric.append(geometric[-1] * r)
if arithmetic.length > 2:
arithmetic_seq.append(arithmetic)
if geometric.length > 2:
geometric_seq.append(geometric)
肯定有一些极端情况需要你解决(留给读者作为练习),但这种方法应该对你有用。对于小序列,订单应通过。对于较大的序列,您可以通过从右到左遍历序列来查看记忆,但这超出了此答案的范围。O(N^3)
编辑
下面是 Python 中的快速实现:
def get_sequences(l):
arithmetic_seq, geometric_seq = [], []
n = len(l)
for i in range(n):
for j in range(i+1, n):
arithmetic, geometric = [l[i], l[j]], [l[i], l[j]]
d = l[j] - l[i]
r = l[j] / l[i]
while (arithmetic[-1] + d) in l:
arithmetic.append(arithmetic[-1] + d)
while (geometric[-1] * r) in l:
geometric.append(int(geometric[-1] * r))
if len(arithmetic) > 2:
arithmetic_seq.append(arithmetic)
if len(geometric) > 2:
geometric_seq.append(geometric)
print("Sequences for ", l)
print("Arithmetic: ", arithmetic_seq)
print("Geometric: ", geometric_seq)
sequences = [[2, 3, 5, 6, 7, 9, 10, 14], [2, 3, 4, 8, 9, 16, 27, 32, 81], [2, 3, 4, 5, 8, 9, 16, 32]]
for seq in sequences:
get_sequences(seq)
这将输出:
Sequences for [2, 3, 5, 6, 7, 9, 10, 14]
Arithmetic: [[2, 6, 10, 14], [3, 5, 7, 9], [3, 6, 9], [5, 6, 7], [5, 7, 9], [6, 10, 14]]
Geometric: []
Sequences for [2, 3, 4, 8, 9, 16, 27, 32, 81]
Arithmetic: [[2, 3, 4], [2, 9, 16]]
Geometric: [[2, 4, 8, 16, 32], [2, 8, 32], [3, 9, 27, 81], [4, 8, 16, 32], [8, 16, 32], [9, 27, 81]]
Sequences for [2, 3, 4, 5, 8, 9, 16, 32]
Arithmetic: [[2, 3, 4, 5], [2, 5, 8], [2, 9, 16], [3, 4, 5]]
Geometric: [[2, 4, 8, 16, 32], [2, 8, 32], [4, 8, 16, 32], [8, 16, 32]]
所以算法是相当正确的。你需要调试你的实现,因为我不确定你使用了什么语言。
评论
0赞
Chi-fung LAM
10/12/2023
使用 AutoIT 实现(参见编辑的帖子),但所有结果都是 -1...需要更多的调试;<
0赞
Abhinav Mathur
10/12/2023
@Chi-fungLAM 编辑了答案。您可以看到算法按预期运行。
0赞
Chi-fung LAM
10/18/2023
最终制定出代码(请参阅编辑后的帖子),非常感谢。
评论
Longest Arithmetic Subsequence
2 4 8 16 32
2 4 8
2 4 8 16