C++ 如果这个if-else-if程序更简单,代码冗余更少(C+;+;),您将如何着手使它变得更简单?
编写一个程序,询问三名跑步者的姓名以及他们各自花费的时间 他们中的一员完成了一场比赛。程序应该显示谁是第一名、第二名和第三名 第三名。 输入验证:只接受时间的正数 我的代码C++ 如果这个if-else-if程序更简单,代码冗余更少(C+;+;),您将如何着手使它变得更简单?,c++,C++,编写一个程序,询问三名跑步者的姓名以及他们各自花费的时间 他们中的一员完成了一场比赛。程序应该显示谁是第一名、第二名和第三名 第三名。 输入验证:只接受时间的正数 我的代码 #include <iostream> #include <string> using namespace std; int main() { string runner1, runner2, runner3; int time1, time2, time3; cout &
#include <iostream>
#include <string>
using namespace std;
int main()
{
string runner1, runner2, runner3;
int time1, time2, time3;
cout << "Please enter the names of three runners" << endl;
cin >> runner1 >> runner2 >> runner3;
cout << "How many minutes did it take " << runner1 << " to finish the race?" << endl;
cin >> time1;
cout << "How many minutes did it take " << runner2 << " to finish the race?" << endl;
cin >> time2;
cout << "How many minutes did it take " << runner3 << " to finish the race?" << endl;
cin >> time3;
if (time1 < time2 && time1 < time3)
{
cout << runner1 << " is 1st place!" << endl;
if (time2 < time3)
{
cout << runner2 << " is 2nd place!" << endl;
cout << runner3 << " is 3rd place!" << endl;
}
else if (time3 < time2)
{
cout << runner3 << " is 2nd place!" << endl;
cout << runner2 << " is 3rd place!" << endl;
}
}
else if (time2 < time1 && time2 < time3)
{
cout << runner2 << " is 1st place!" << endl;
if (time1 < time3)
{
cout << runner1 << " is 2nd place!" << endl;
cout << runner3 << " is 3rd place!" << endl;
}
else if (time3 < time1)
{
cout << runner3 << " is 2nd place!" << endl;
cout << runner2 << " is 3rd place!" << endl;
}
}
else if (time3 < time2 && time3 < time1)
{
cout << runner3 << " is 1st Place!" << endl;
if (time2 < time1)
{
cout << runner2 << " is 2nd place!" << endl;
cout << runner1 << " is 3rd place!" << endl;
}
else if (time1 < time2)
{
cout << runner1 << " is 2nd place!" << endl;
cout << runner2 << " is 3rd place!" << endl;
}
}
else
{
cout << "Error! Please restart the program and input a positive value" << endl;
}
return 0;
}
#包括
#包括
使用名称空间std;
int main()
{
字符串runner1、runner2、runner3;
int time1,time2,time3;
cout runner1>>runner2>>runner3;
cout让跑步者按时间在数组中排序,迭代跑步者数组并输出(name+i+“place”)
我认为一个链表会非常好,但是如果跑步者不经常更换位置或者跑步者不多,它可能会输给一个原始数组
“将绘图代码与游戏逻辑分离”
你的绘图代码是cout calls。你的游戏逻辑是确定每个跑步者的位置。然后你根据你计算的状态绘图
您的方法是最直接和最快的方式来解决打印出亚军位置的问题
#include "stdafx.h"
#include <iostream>
#include <algorithm>
using namespace std;
struct Runner {
int time;
int id;
int operator<(Runner runner) {
return time < runner.time;
}
};
char* pickSuffix(int place) {
switch (place) {
case 1:
return "st";
case 2:
return "nd";
case 3:
return "rd";
default:
return "th";
}
}
int main() {
//make my runners, read in my times, runner 1 first
Runner runners[3];
for (int i = 0; i < 3; i++) {
cout << "Enter runner " << i+1 << "'s time: ";
cin >> runners[i].time;
cout << endl;
runners[i].id = i+1; //setup their id, used like a name
}
//figure out what place each runner came in
//must overload operator< for object to use sort
sort(runners, &runners[2]);
//the position of the runner in the array is the place they came in
//since it is sorted by their times
for (int i = 0; i < 3; i++) {
cout << "Runner #" << runners[i].id << " came in " << i+1 << pickSuffix(i+1) << " place!" << endl;
cout << runners[i].time << endl;
}
system("pause");
return 0;
}
#包括“stdafx.h”
#包括
#包括
使用名称空间std;
结构转轮{
整数时间;
int-id;
It运算符看起来你开始了C++编程的旅程。欢迎。
我试图将问题分解为各个组成部分,以便最终以易于理解的形式表达解决方案的意图:
int solve(std::istream& is, std::ostream& os) {
Runners runners;
collect_runners(os, is, runners);
sort_by_time(runners);
print_first_3(os, runners);
return 0;
}
请注意,我没有将解决方案绑定到任何特定的输入或输出流,因此我可以在以后轻松地测试它
现在,我们已经清楚地表达了解决方案的意图,我们填补了空白(我使用了各种“高级”技术,希望您会发现这些技术很有启发性和有趣)
我用过c++11
在线评论
#include <string>
#include <vector>
#include <algorithm>
#include <type_traits>
#include <iostream>
#include <sstream>
/** The concept of coupling a runner's name with the time it took to run the race
*
*/
struct Runner {
std::string name;
int time;
};
/** A collection of runners and their corresponding time.
*
*/
using Runners = std::vector<Runner>;
/** Sort a container with a predicate. Return a reference to the container
*
* @tparam Container
* @tparam Pred
* @param c
* @param pred
* @return
*/
template<class Container, class Pred>
auto sort_container(Container &c, Pred &&pred) -> Container & {
std::sort(std::begin(c), std::end(c), std::forward<Pred>(pred));
return c;
}
/** Sort a Runners array by ascending time
*
* @param vec
* @return
* */
Runners &sort_by_time(Runners &vec) {
auto by_increasing_time = [](Runner const& l, Runner const& r) {
return l.time < r.time;
};
sort_container(vec, by_increasing_time);
return vec;
}
/** Print the first 3 runnes in an array of runners to an ostream
*
* @param os
* @param vec
*/
void print_first_3(std::ostream& os, Runners const &vec) {
static const char *nth[] = {
"first",
"second",
"third"
};
auto limit = std::extent<decltype(nth)>::value;
limit = std::min(limit, vec.size());
for (std::size_t i = 0; i < limit; ++i) {
auto const &runner = vec[i];
os << runner.name << " is in " << nth[i] << " place with a time of " << runner.time << "\n";
}
}
/** Ask a question on the console if the answer is to come from stdin
*
* @param is
* @param q
*/
template<class Target>
void question(std::istream& is, Target& target, std::string const& q)
{
if (std::addressof(is) == static_cast<std::istream*>(std::addressof(std::cin)))
{
std::cout << q << std::endl;
}
is >> target;
}
/** Build a runner using the supplied input and output streams
*
* @param os
* @param is
* @return
*/
Runner collect_runner(std::ostream& os, std::istream& is)
{
Runner runner {};
question(is, runner.name, "runner's name?");
question(is, runner.time, "runner's time?");
return runner;
}
/** Populate a Runners array using input and output streams
*
* @param os
* @param is
* @param runners
* @return
*/
Runners& collect_runners(std::ostream& os, std::istream& is, Runners& runners)
{
int nrunners = 0;
question(is, nrunners, "how many runners?");
while (nrunners-- > 0) {
runners.push_back(collect_runner(os, is));
}
return runners;
}
/** Solve the problem at hand
*
* @param is
* @param os
* @return
*/
int solve(std::istream& is, std::ostream& os) {
Runners runners;
collect_runners(os, is, runners);
sort_by_time(runners);
print_first_3(os, runners);
return 0;
}
/** Solve the problem using either std input/output or test input
*
* @param argc
* @param argv
* @note If argc == 2 and argv[1] == "test" then run solve using test input.
* We do this so that we can test our code without playing around with external files or
* the console each time we want to test it
* @return
*/
int main(int argc, char **argv) {
if (argc == 2 && argv[1] == std::string("test")) {
static const char test_data[] = R"__(
5
bob 40
bill 20
sue 30
peter 25
zool 29
)__";
std::istringstream test_stream{test_data};
return solve(test_stream, std::cout);
} else {
return solve(std::cin, std::cout);
}
}
预期产出:
bill is in first place with a time of 20
peter is in second place with a time of 25
zool is in third place with a time of 29
我可能对理查德回答的复杂性感到惊讶
当然,他在组织代码方面提出了很好的观点
我最后发布了自己的评论和一个“更简单”的示例,因为我认为程序最重要的一面是功能性
在这种情况下,
- 您需要错误处理(用户可能输入非法值)
- 您需要检查输入(用户可以输入3个以上的名称,也可以输入相同的名称等)
- 您需要正确地报告排名。如果两名跑步者同时跑步,您将按“任意”顺序对他们进行排名。您将希望将他们正确地评定为共享位置
我的代码
- 与3名跑步者的联系较少(仅在阅读这三个名字时,因为这是示例所要求的)
- 举例说明如何使用
部分排序
仅对前3个位置进行排序,这已不再可能,因为显示功能处理未知大小的集合,共享位置意味着可能有3个以上的排名跑步者
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
void static inline ignore_rest_of_line() {
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
struct Runner {
std::string name;
int time = 0;
bool operator<(Runner const& o) const { return time < o.time; }
};
std::vector<Runner> read_three() {
std::string name1, name2, name3;
auto unique = [&] { return std::set<std::string>{ name1, name2, name3 }.size() == 3; };
std::cout << "Please enter the names of three runners\n";
while (std::cin) {
if (std::cin >> name1 >> name2 >> name3 && unique())
break;
std::cout << "Enter 3 unique names\n";
ignore_rest_of_line();
}
ignore_rest_of_line();
return { { name1, 0 }, { name2, 0 }, { name3, 0 } };
}
void read_time(Runner& runner) {
while (std::cin) {
std::cout << "How many minutes did it take " << runner.name << " to finish the race?\n";
if ((std::cin >> runner.time) && runner.time > 0)
break;
std::cout << "Enter a valid time\n";
std::cin.clear();
ignore_rest_of_line();
}
ignore_rest_of_line();
}
template <typename List>
void display_winners(List runners) {
std::sort(std::begin(runners), std::end(runners));
std::string ranks[] = { "1st", "2nd", "3rd" };
auto prev = runners.begin();
auto rank = std::begin(ranks);
for (auto& runner : runners) {
if (runner.time != prev->time)
++rank;
if (rank == std::end(ranks))
break;
std::cout << runner.name << " is " << *rank << " place\n";
}
}
int main() {
std::cin.exceptions(std::ios::eofbit);
auto runners = read_three();
for (auto& runner : runners) {
read_time(runner);
}
display_winners(runners);
}
#包括
#包括
#包括
#包括
#包括
无效静态内联忽略\u行()的\u剩余\u{
std::cin.ignore(std::numeric_limits::max(),'\n');
}
结构运行程序{
std::字符串名;
整数时间=0;
布尔运算符name1>>name2>>name3&&unique()
打破
std::你展示的程序能工作吗?它能生成吗?它能运行吗?它能产生预期的结果吗?那么你想要的是代码审查,你应该在这里发布,而不是在这里发布。@OP我会从改进代码布局开始,这样它会读得更好。因为问题是按它的方式写的,对我来说听起来像是家庭作业。所以这里是一些提示:1.每个运行程序都有一个对应的时间,因此将它们捆绑到一个类或结构中是有意义的。2.通过比较它们的运行时间,可以对此类成员进行排序。3.通过将它们存储在STL容器中进行排序,并通过std::Sort
(或类似方式)对它们进行排序4.通过遍历已排序的容器打印出谁有一个。如果您有问题,请尝试一下,然后返回这里。因此,没有代码编写服务。我投票关闭这个问题,因为它属于codereview.stackexchange.com。虽然这不是最好的问题,但它下面隐藏着一个好问题他的。这里的基本问题是有3!=6个分支,这显然不可伸缩。有趣的是,sort\u container
实现的注释比代码多,后面返回,完美转发等等。我本来想在这个评论中发布一个竞争性的示例,但发现我添加了一些有用的东西,所以升级到一个答案。。。@两个人的想法总比一个人好。去做吧。我希望这里有像你这样的人来帮我写这个rpc库,而不是一个人写…谢谢你。我的答案是:)+1“从游戏逻辑中分离绘图”.这是一个很好的建议。我刚刚意识到我的部分排序
在这里是不正确的,以防列表更大并且有许多共享位置(您可能需要打印3个以上的名称,并且它们都应该按顺序排列).已修复。您还记得我同意向您展示我为asio制作对象的方法吗?这里有一个快速演示:git@github.com:madmongo1/goblins.gitI do!我差点错过了这条评论。很快就从中克隆出来:)我认为值得注意的是,尽管Richard的答案显然更长,但并不十分复杂。乍一看,它看起来像e其McCabe圈复杂度(仅举一个例子)是2。虽然可以实现,但大多数人发现结果……最多有点奇怪。@JerryCoffin这都是相对的,而且,相对而言,对学生来说是主观的。但是,是的,我的答案并没有降低复杂性。但它确实提高了输入验证和逻辑:)这是我的观点。我本来打算展示一个精简版,但是然后我意识到这个问题被低估了(一如既往)
#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <set>
void static inline ignore_rest_of_line() {
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
struct Runner {
std::string name;
int time = 0;
bool operator<(Runner const& o) const { return time < o.time; }
};
std::vector<Runner> read_three() {
std::string name1, name2, name3;
auto unique = [&] { return std::set<std::string>{ name1, name2, name3 }.size() == 3; };
std::cout << "Please enter the names of three runners\n";
while (std::cin) {
if (std::cin >> name1 >> name2 >> name3 && unique())
break;
std::cout << "Enter 3 unique names\n";
ignore_rest_of_line();
}
ignore_rest_of_line();
return { { name1, 0 }, { name2, 0 }, { name3, 0 } };
}
void read_time(Runner& runner) {
while (std::cin) {
std::cout << "How many minutes did it take " << runner.name << " to finish the race?\n";
if ((std::cin >> runner.time) && runner.time > 0)
break;
std::cout << "Enter a valid time\n";
std::cin.clear();
ignore_rest_of_line();
}
ignore_rest_of_line();
}
template <typename List>
void display_winners(List runners) {
std::sort(std::begin(runners), std::end(runners));
std::string ranks[] = { "1st", "2nd", "3rd" };
auto prev = runners.begin();
auto rank = std::begin(ranks);
for (auto& runner : runners) {
if (runner.time != prev->time)
++rank;
if (rank == std::end(ranks))
break;
std::cout << runner.name << " is " << *rank << " place\n";
}
}
int main() {
std::cin.exceptions(std::ios::eofbit);
auto runners = read_three();
for (auto& runner : runners) {
read_time(runner);
}
display_winners(runners);
}