草庐IT

c++ - 我应该尝试返回一个数组,还是有更好的解决方案?

coder 2024-02-13 原文

一个问题set对于学习 C++ 的人来说是

Write a short program to simulate a ball being dropped off of a tower. To start, the user should be asked for the initial height of the tower in meters. Assume normal gravity (9.8 m/s2), and that the ball has no initial velocity. Have the program output the height of the ball above the ground after 0, 1, 2, 3, 4, and 5 seconds. The ball should not go underneath the ground (height 0).

在开始使用 C++ 之前,我有一定的 Java 知识,但主要是自学的。所以看看这个问题,它似乎应该被分成

  • 输入类
  • 输出类
  • 计算课
  • 物理常数类(出题人推荐)
  • Controller ('main')类

输入类会询问用户起始高度,该高度将传递给 Controller ​​。 Controller 会将这个和数秒 (5) 提供给计算类,计算类将创建一个结果数组并将其返回给 Controller 。 Controller 会将结果数组传递给输出类,输出类将结果打印到控制台。

我会将实际代码放在底部,但可能不需要。

您可能已经看到了问题,试图返回一个数组。我不是在问如何解决这个问题,有一个解决方法 herehere .我在问,问题是不是设计不当造成的?出于性能、维护或样式的原因,我的程序是否应该采用不同的结构,这样我就不会尝试返回一个类似对象的数组

这是代码(除了尝试返回数组外);

主要.cpp

/*
 * Just the main class, call other classes and passes variables around
 */
#include <iostream>
#include "dropSim.h"
using namespace std;

int main()
{
    double height = getHeight();
    int seconds = 5;
    double* results = calculateResults(height, seconds);
    outputResults(results);
    return 0;
}

获取高度.cpp

/*
 *  Asks the user for a height from which to start the experiment
 *  SI units
 */
#include <iostream>
using namespace std;

double getHeight()
{
    cout << "What height should the experiment start at; ";
    double height;
    cin >> height;
    return height;
}

计算结果.cpp

/*
 * given the initial height and the physical constants, the position of the ball
 * is calculated at integer number seconds, beginning at 0
 */

#include "constants.h"
#include <cmath>
#include <iostream>
using namespace std;

double getPosition(double height, double time);

double* calculateResults(double height, int seconds)
{

    double positions[seconds + 1];
    for(int t = 0; t < seconds + 1; t++)
    {
        positions[t] = getPosition(height, t);
    }
    return positions;
}

double getPosition(double height, double time)
{
    double position = height - 0.5*constants::gravity*pow(static_cast<double>(time), 2);
    if( position < 0) position = 0;
    //Commented code is for testing
    //cout << position << endl;
    return position;
}

输出结果.cpp

/*
 *      Takes the array of results and prints them in an appropriate format
 */


#include <iostream>
#include <string>
#include <sstream>

using namespace std;

void outputResults(double* results){
    string outputText = "";
    //The commented code is to test the output method
    //Which is working
    //double results1[] = {1,2,3,4,5};
    //int numResults = sizeof(results1)/sizeof(results1[0]);
    int numResults = sizeof(results)/sizeof(results[0]);
    //cout << numResults; //= 0 ... Oh
    for(int t = 0; t < numResults; t++)
    {
        ostringstream line;
        line << "After " << t << " seconds the height of the object is " << results[t] << "\r";
        outputText.append(line.str());

    }
    cout << outputText;
}

最后是几个标题; dropSim.h

/*
 * dropSim.h
 */

#ifndef DROPSIM_H_
#define DROPSIM_H_

double getHeight();

double* calculateResults(double height, int seconds);

void outputResults(double* results);

#endif /* DROPSIM_H_ */

常量.h

/*
 *      Contains physical constants relevant to simulation.
 *      SI units
 */

#ifndef CONSTANTS_H_
#define CONSTANTS_H_

namespace constants
{
    const double gravity(9.81);
}

#endif /* CONSTANTS_H_ */

最佳答案

我会说你过度设计了一个小问题的大解决方案,但要回答你的具体问题:

Should my program be structured differently, for performance, maintenance or style reasons, such that I would not be attempting to return an array like object?

返回一个类似数组的对象是可以的。但这并不意味着返回数组,也不意味着使用 new 分配原始内存。

而且它也不限于返回值。当您开始使用 C++ 时,最好完全忘记它具有内置数组。大多数时候,您应该使用 std::vectorstd::array(或另一个线性集合,例如 std::deque).

内置数组通常应被视为具有特殊用途的项目,主要是为了与 C 兼容,而不是日常使用。

但是,可能值得考虑以与标准库中的算法相同的风格编写您的计算。这意味着编写代码以将迭代器接收到目的地,并将其输出写入迭代器指定的任何位置。

我可能会将高度和时间打包为一组输入参数,并有一个基于这些参数生成输出的函数:

struct params {
    double height;
    int seconds;
};

template <class OutIt>
void calc_pos(params const &p, OutIt output) { 
    for (int i=0; i<p.seconds; i++) {
        *output = get_position(p.height, i);
        ++output;
    }
}

这与标准库的其余部分一起工作得更清楚:

std::vector<double> results;

calc_pos(inputs, std::back_inserter(results));

如果您愿意,您可以更进一步——标准库在这方面有很多帮助。您的 calc_pos 只是用当时的连续值重复调用另一个函数。您可以(例如)使用 std::iota 生成连续时间,然后使用 std::transform 生成输出:

std::vector<int> times(6);

std::iota(times.begin(), times.end(), 0);

std::vector<double> distances;

std::transform(times.begin(), times.end(), compute_distance);

这里计算的距离是在给定时间段后下降的距离,而不是地面以上的高度,但给定初始高度,计算两者之间的差异是非常微不足道的:

double initial_height = 5;

std::vector<double> heights;

std::transform(distances.begin(), distances.end(), 
    std::back_inserter(heights),
    [=](double v) { return max(initial_height-v, 0); });

至少现在,这不会尝试计算球在撞击地面时的弹跳——它只是假设球在撞击地面时立即停止。

关于c++ - 我应该尝试返回一个数组,还是有更好的解决方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30646677/

有关c++ - 我应该尝试返回一个数组,还是有更好的解决方案?的更多相关文章

  1. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  2. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  3. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  4. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  5. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

  6. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  7. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  8. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  9. ruby - 检查 "command"的输出应该包含 NilClass 的意外崩溃 - 2

    为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar

  10. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

随机推荐