想象一下,我们有一个循环,其索引变量n
从1到6。当我完成此循环时,我想打印值
1
2
3
3
2
1
是否存在可以实现此目标的精妙数学运算(即避免使用if
语句)?我知道例如我是否打印
1 + modulo(n-1,3)
它将打印
1
2
3
1
2
3
但是我希望下半场倒转。如果有帮助,循环将始终具有偶数次迭代。我正在用Fortran 90编写。
答案 0 :(得分:2)
以下内容如何:
do i=1,n
print *, int(abs(i-n/2.0-0.5)+0.5)
end do
这将打印偶数n
的预期结果,并为奇数n
引入零。
答案 1 :(得分:2)
以下内容足够优雅吗?我认为这比模糊的数学要清楚得多
ian-admin@agon ~/work/stack $ cat merge.f90
Program test
Implicit None
Integer :: n
Integer :: i
Write( *, * ) 'n?'
Read ( *, * ) n
Do i = 1, n
Write( *, * ) Merge( i, n - ( i - 1 ), i <= n / 2 )
End Do
End Program test
ian-admin@agon ~/work/stack $ gfortran -std=f2003 -Wall -Wextra merge.f90
ian-admin@agon ~/work/stack $ ./a.out
n?
6
1
2
3
3
2
1
ian-admin@agon ~/work/stack $ ./a.out
n?
7
1
2
3
4
3
2
1
ian-admin@agon ~/work/stack $
答案 2 :(得分:1)
考虑
min(n, 7-n)
此表达式在1, 2, 3, 3, 2, 1
从n
到1
时产生6
。更一般而言,如果N
是变量n
的(偶数)上限,则公式变为:
min(n, N+1-n)
产生
1, 2, ..., N/2, N/2, N/2 - 1, ..., 2, 1
n
在1
和N
之间运行。
在N
为奇数的情况下,相同的公式会生成序列
1, 2, ..., (N+1)/2, (N-1)/2, ..., 2, 1.
例如:
1, 2, 3, 4, 3, 2, 1
N=7
。
答案 3 :(得分:0)
n = 6
for i in range(1,n+1):
print(min(i, n + 1 - i))
or (// is integer division equivalent to bitshift right)
print(n//2 - abs(n + 1 - 2 * i)//2)
>> 1 2 3 3 2 1
对于奇数长度-第一种方法按原样工作,第二种方法要求更改为(n+1)//2
(对于偶数长度,它不会中断工作)
找出两个32位整数中最小值的位的技巧:
min = b+((a-b)&((a-b)>>31))