给定 Integer n 和 Double x。计算:sin x + sin sin x +...+sin sin...sin x。其中n——罪的数目
given Integer n and Double x. Calculate: sin x + sinsin x +...+sinsin...sinx. Where n— number of sin
我写道:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Test1 {
public static void main(String[] args) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String sn = reader.readLine();
String sx = reader.readLine();
int n = Integer.parseInt(sn);
double x = Double.parseDouble(sx);
double sum = 0;
for (int i = 0; i < n; i++) {
x = Math.sin(x);
sum += x;
}
System.out.println("Sum is: " + sum);
} catch (Exception e) {
}
}
}
但是讲师说,这个代码错了
很明显你的答案是 sum of n
term where the i
th term has i
正弦嵌套链。
这是执行此操作的代码。请注意,通过使用正确的变量名称和对解决方案的结构进行推理,一切都变得非常清晰。
class Potato
{
public static void main(String args[])
{
double x = 0.5;
int n = 2;
double sum = 0;
for(int i=1;i<=5;i++)
{
double term = x;
for(int j=1;j<=i;j++)
term = Math.sin(term);
sum += term;
}
System.out.println(sum);
}
}
对于我这里的特定值,序列是
sin(0.5) + sin(sin(0.5)) ==> 0.9406950936373837
同样使用此 python 片段手动确认:
>>> sin(0.5) + sin(sin(0.5))
0.9406950936373837
但是,你的代码也是正确的,而且效率更高,避免了重复计算。
要了解为什么这是真的:
你可以把term[i]
写成sin(term[i-1])
所需的答案是 sum(term)
,这正是您计算得出的结果。
如果你想效率高一点,也可以这样做:
public static double sum(double x, int n) {
assert n >= 1;
double sum = 0;
double term = x;
for (int i = 0; i < n; ++i) {
term = Math.sin(term);
sum = sum + term;
}
return sum;
}
测试:
public static void test() {
double x = Math.PI / 2;
System.out.println(sum(x, 1) + " " + Math.sin(x));
System.out.println(sum(x, 2) + " " + (Math.sin(x) + Math.sin(Math.sin(x))));
System.out.println(sum(x, 3) + " " + (Math.sin(x) + Math.sin(Math.sin(x)) + Math.sin(Math.sin(Math.sin(x)))));
}
测试输出(两个版本):
1.0 1.0
1.8414709848078965 1.8414709848078965
2.5870951264734545 2.5870951264734545
递归版本
public static double sum(double x, double n) {
return sum(x, n, Math.sin(x));
}
public static double sum(double x, double n, double term) {
if (n == 0) {
return 0;
}
return term + sum(x, n - 1, Math.sin(term));
}
您的代码的内部主体,即实际计算答案的算法部分是正确的。
您可以使用 ghci 的交互式 Haskell 会话来检查该部分(这使得重复函数调用等操作变得更加简单)。
例如使用 Haskell 计算可以简化为:(\x n -> sum . tail . take (n+1) $ iterate sin x) 0.5 2
,计算 x = 0.5
和 n = 2
并产生 0.9406950936373837
但您可能需要重新阅读问题。输入应该是度数而不是弧度吗?鉴于重复函数应用的模式,输出可能应该是 x + sin(x) + ...
,在这种情况下,用于验证目的的 Haskell 代码将是:
(\x n -> sum . take n $ iterate sin x)
和 x = 0.5
和 n = 2
的相同示例将产生 0.979425538604203
而且你的解决方案有一个问题:如果没有输入怎么办?如果只有一根线怎么办?你假设你总是会得到 2 行,但是......情况可能并非如此。你没有任何错误处理。
另外,也许老师要求你把你的重复正弦之和的算法放在它自己的函数中?
我写道:
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Test1 {
public static void main(String[] args) {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String sn = reader.readLine();
String sx = reader.readLine();
int n = Integer.parseInt(sn);
double x = Double.parseDouble(sx);
double sum = 0;
for (int i = 0; i < n; i++) {
x = Math.sin(x);
sum += x;
}
System.out.println("Sum is: " + sum);
} catch (Exception e) {
}
}
}
但是讲师说,这个代码错了
很明显你的答案是 sum of n
term where the i
th term has i
正弦嵌套链。
这是执行此操作的代码。请注意,通过使用正确的变量名称和对解决方案的结构进行推理,一切都变得非常清晰。
class Potato
{
public static void main(String args[])
{
double x = 0.5;
int n = 2;
double sum = 0;
for(int i=1;i<=5;i++)
{
double term = x;
for(int j=1;j<=i;j++)
term = Math.sin(term);
sum += term;
}
System.out.println(sum);
}
}
对于我这里的特定值,序列是
sin(0.5) + sin(sin(0.5)) ==> 0.9406950936373837
同样使用此 python 片段手动确认:
>>> sin(0.5) + sin(sin(0.5))
0.9406950936373837
但是,你的代码也是正确的,而且效率更高,避免了重复计算。
要了解为什么这是真的:
你可以把term[i]
写成sin(term[i-1])
所需的答案是 sum(term)
,这正是您计算得出的结果。
如果你想效率高一点,也可以这样做:
public static double sum(double x, int n) {
assert n >= 1;
double sum = 0;
double term = x;
for (int i = 0; i < n; ++i) {
term = Math.sin(term);
sum = sum + term;
}
return sum;
}
测试:
public static void test() {
double x = Math.PI / 2;
System.out.println(sum(x, 1) + " " + Math.sin(x));
System.out.println(sum(x, 2) + " " + (Math.sin(x) + Math.sin(Math.sin(x))));
System.out.println(sum(x, 3) + " " + (Math.sin(x) + Math.sin(Math.sin(x)) + Math.sin(Math.sin(Math.sin(x)))));
}
测试输出(两个版本):
1.0 1.0
1.8414709848078965 1.8414709848078965
2.5870951264734545 2.5870951264734545
递归版本
public static double sum(double x, double n) {
return sum(x, n, Math.sin(x));
}
public static double sum(double x, double n, double term) {
if (n == 0) {
return 0;
}
return term + sum(x, n - 1, Math.sin(term));
}
您的代码的内部主体,即实际计算答案的算法部分是正确的。
您可以使用 ghci 的交互式 Haskell 会话来检查该部分(这使得重复函数调用等操作变得更加简单)。
例如使用 Haskell 计算可以简化为:(\x n -> sum . tail . take (n+1) $ iterate sin x) 0.5 2
,计算 x = 0.5
和 n = 2
并产生 0.9406950936373837
但您可能需要重新阅读问题。输入应该是度数而不是弧度吗?鉴于重复函数应用的模式,输出可能应该是 x + sin(x) + ...
,在这种情况下,用于验证目的的 Haskell 代码将是:
(\x n -> sum . take n $ iterate sin x)
和 x = 0.5
和 n = 2
的相同示例将产生 0.979425538604203
而且你的解决方案有一个问题:如果没有输入怎么办?如果只有一根线怎么办?你假设你总是会得到 2 行,但是......情况可能并非如此。你没有任何错误处理。
另外,也许老师要求你把你的重复正弦之和的算法放在它自己的函数中?