问题的文本:
输入:输入流包含一组整数Ai(0≤Ai≤1018)。数字由任意数量的空格和换行符分隔。输入流的大小不超过256 KB。
输出:对于从最后一个到第一个的每个数字Ai,您应输出其平方根。每个平方根应打印在一个单独的行中,小数点后至少有四位数。
示例
输入:
1427 0876652098643267843 5276538
输出:
2297.0716 936297014.1164 0.0000 37.7757
时限:2.0秒
内存限制:16 MB
C和C ++程序由32位Microsoft Visual C ++ 2010在服务器上编译。直到2010年8月3日,才使用了英特尔C ++编译器7.0。您可以在此页面上下载Microsoft Visual Studio 2010 Express的免费副本。使用以下参数调用编译器:
// C cl /TC /MT /EHsc /O2 /W3 /Za /D "_CRT_SECURE_NO_WARNINGS" /D "_CRT_SECURE_NO_DEPRECATE" /D "ONLINE_JUDGE" // C++ cl /TP /MT /EHsc /O2 /W3 /Za /D "_CRT_SECURE_NO_WARNINGS" /D "_CRT_SECURE_NO_DEPRECATE" /D "ONLINE_JUDGE"
这是我在gcc 4.3中解决这个问题的方法:
#include <iostream>
#include <list>
#include <string>
#include <sstream>
#include <math.h>
#include <algorithm>
#include <iomanip>
#include <stdio.h>
void sqrt_f(double n)
{
printf ( "%.4f\n", sqrt( static_cast<double>( n ) ) );
}
int main()
{
std::list<double> numbers;
std::string sInput;
getline( std::cin, sInput );
std::istringstream parse( sInput );
double tmp;
while ( parse >> tmp )
numbers.push_front( tmp );
std::for_each(numbers.begin(), numbers.end(), sqrt_f);
return 0;
}
但判断结果是:错误答案(test1)
有什么问题?
答案 0 :(得分:3)
警告:当我写这篇文章时,问题仍然存在于代码审查网站上,所以它主要是作为代码审查编写的。主要应用于SO(修复输入问题)的部分几乎没有提及。
目前,我将假设你已经解决了问题@Jeff Mercado指出要获得类似这样的代码:
#include <iostream>
#include <list>
#include <string>
#include <sstream>
#include <math.h>
#include <algorithm>
#include <iomanip>
#include <stdio.h>
void sqrt_f(double n)
{
printf ( "%.4f\n", sqrt( static_cast<double>( n ) ) );
}
int main()
{
std::list<double> numbers;
std::string sInput;
while (getline( std::cin, sInput )) { // added `while` to process all input
std::istringstream parse( sInput );
double tmp;
while ( parse >> tmp )
numbers.push_front( tmp );
}
std::for_each(numbers.begin(), numbers.end(), sqrt_f);
return 0;
}
然后,我将忽略您实际提出的问题(关于正确性),并且只是检查(重写)代码,假设它符合要求。
void sqrt_f(double n)
{
printf ( "%.4f\n", sqrt( static_cast<double>( n ) ) );
}
我在这里看到三件我不太喜欢的事情:
n
已经是双倍的。)关注点分离不佳。您将计算与I / O结合起来。
std::list<double> numbers;
我认为没有太多理由在这里使用std::list
。你只是在一端插入,并且从头到尾遍历。使用std::list
的主要原因是您要在列表中间的某处插入/删除。即使这样,它也不一定是最好的选择,但是当你只需要插入一端时,几乎肯定是错误的选择。
std::string sInput;
while (getline( std::cin, sInput )) { // added `while` to process all input
double tmp;
while ( parse >> tmp )
numbers.push_front( tmp );
}
我认为没有任何真正的理由在这里使用std::getline
。 getline
主要用于输入具有面向行的格式,但这里只是由一些任意数量的空格分隔的双精度流。为此,您似乎增加了额外的复杂性而没有获得太多功能作为回报。
我对循环while (parse >> tmp)
也不太兴奋。它肯定比某些替代方案更好,但我宁愿使用std::copy
(在这种情况下)std::istream_iterator<double>
将值复制到集合中。
我对你如何使用这个系列并不是特别兴奋。首先,您使用push_front
来撤销订单。至少对我而言,如果您按照原始顺序将数字添加到集合中,然后向后浏览集合,似乎更容易理解。
std::for_each(numbers.begin(), numbers.end(), sqrt_f);
......这是导致sqrt_f
责任分离不良的罪魁祸首。自从STL来到C ++以来已经有15年了,在那个时候我怀疑我已经看到了std::for_each
的多达六种好用途。它可以有用,但通常应该是你最后选择的算法,当你找不到其他更好的东西时。
我认为如果我这样做,我会使用std::vector
进行存储(我们只需要在一端添加项目,这符合vector
提供的内容)。我使用带有std::copy
的{{1}}将数据直接从std :: cin复制到该向量中。然后,我将std::istream_iterator<double>
与向量上的一对反向迭代器一起使用,并为输出使用std::transform
。由于固定标志和精度都是“粘性”,我们可以通过在调用ostream_iterator
之前设置一次格式来获得正确格式的所有输出:
std::transform