在操作后使用向量的原始值

时间:2018-04-05 13:02:07

标签: c++ vector

我正在尝试将从文件接收的矢量值转换为两种不同的格式。转换成第一种格式并打印出矢量后,我想使用原文"读入"将它们转换为第二种格式的值。

目前,似乎第二次转换发生在已转换的值上。但是,我不明白为什么它不会转换回原来的价值呢?最后,我如何使用矢量的原始值进行第二次转换,以便

else {
        GetType();
        GetXArg();
        GetYArg();
    }

第二次工作?

以下是代码段:

void Force::convToP()  //converts to polar
{
    if (forceType == 'c')
    {
        SetType('p');
        SetXArg(sqrt(xArg * xArg + yArg * yArg));
        SetYArg(atan(yArg / xArg));
    }
    else {
        GetType();  //just return type, xArg and yArg in their original form
        GetXArg();
        GetYArg();
    }

}

void Force::convToC()  //converts to cartesian
{
    if (forceType == 'p') {
        SetType('c');
        SetXArg(xArg * cos(yArg));
        SetYArg(xArg * sin(yArg));
    }
    else {
        GetType();
        GetXArg();
        GetYArg();
    }
}

和主要功能:

while (file >> type >> x >> y) {
        Force f(type, x, y);
        force.push_back(f);
    }
    for (int i = 0; i < force.size(); ++i) {
        force[i].printforce();
    }

    cout << "Forces in Polar form: " << endl;
    for (int i = 0; i < force.size(); ++i)
    {
        force[i].convToP();
        force[i].printforce();
    }

    cout << "Forces in Cartesian form: " << endl;
    for (int i = 0; i < force.size(); ++i) {
        force[i].convToC();
        force[i].printforce();
    }

最后,目前的输出是:

p 10 0.5
c 12 14
p 25 1
p 100 0.8
c 50 50
p 20 3.14
c -100 25
p 12 1.14

Forces in Polar form:  <-first conversion. All works fine

p 10 0.5  
p 18.4391 0.649399
p 25 1
p 100 0.8
p 70.7107 0.61548
p 20 3.14
p 103.078 0.237941
p 12 1.14

Forces in Cartesian form:

c 8.77583 4.20736 <-works fine
c 14.6858 8.8806  <-why doesn't convert back to c 12 14/ how to use the original values of vector
c 13.5076 11.3662
c 69.6707 49.9787
c 57.735 33.3333
c -20 -0.0318509
c 100.173 23.6111
c 5.01113 4.55328
Press any key to continue . . .

对此非常陌生,困惑了一段时间,所以非常感谢任何帮助和建议。

4 个答案:

答案 0 :(得分:4)

您正在修改xArg,然后使用修改后的值转换yArg。在修改之前,您需要进行两次转换。

void Force::convToP()  //converts to polar
{
    if (forceType == 'c')
    {
        forceType = 'p';
        decltype(xArg) newX = sqrt(xArg * xArg + yArg * yArg);
        decltype(yArg) newY = atan(yArg / xArg);
        xArg = newX;
        yArg = newY
    }
    // no else needed
}

void Force::convToC()  //converts to cartesian
{
    if (forceType == 'p') {
        forceType = 'c';
        decltype(xArg) newX = xArg * cos(yArg);
        decltype(yArg) newY = xArg * sin(yArg);
        xArg = newX;
        yArg = newY
    }
    // no else needed
}

您可以使用the correct values

验证std::complex
#include <complex>
#include <vector>
#include <iostream>

int main() {

    std::vector<std::complex<double>> nums
    {
        std::polar<double>(10, 0.5),
        std::complex<double>(12, 14),
        std::polar<double>(25, 1),
        std::polar<double>(100, 0.8),
        std::complex<double>(50, 50),
        std::polar<double>(20, 3.14),
        std::complex<double>(-100, 25),
        std::polar<double>(12, 1.14)
    };

    for (auto num : nums) 
    { 
        std::cout << num << " (" << std::abs(num) << ", " << std::arg(num) << ")\n";
    }
}
(8.77583,4.79426) (10, 0.5)
(12,14) (18.4391, 0.86217)
(13.5076,21.0368) (25, 1)
(69.6707,71.7356) (100, 0.8)
(50,50) (70.7107, 0.785398)
(-20,0.0318531) (20, 3.14)
(-100,25) (103.078, 2.89661)
(5.01113,10.9036) (12, 1.14)

答案 1 :(得分:1)

将子操作分解为小的单一关注函数通常很有帮助。

编译器将优化掉所有冗余副本,加载和存储:

#include <cmath>
#include <tuple>

auto computed(double xArg, double yArg) 
{
    return 
        std::make_tuple(
            std::sqrt(xArg * xArg + yArg * yArg),
            std::atan(yArg / xArg));
}

void modify(double& xArg, double& yArg)
{
    std::tie(xArg, yArg) = computed(xArg, yArg);
}

答案 2 :(得分:0)

您的转换功能显然会更改其操作的对象。然后,您需要注意索引运算符([])将引用返回给向量中的对象。如果您不想修改原始对象,则必须复制以下内容:

for (int i = 0; i < force.size(); ++i)
{
    auto copy = force[i]
    copy.convToP();
    copy.printforce();
}

现在,您可以在第二次运行中操作未更改的值。假设您之后不再需要原始值,您可以按原样保留第二个循环,否则,再次复制...

基于循环的范围更容易一些:

for(auto c : force)
{
    c.convToP();
    c.printforce();
}

for(auto& c : force)
//      ^ if you don't need original values any more, can use reference now
{
    c.convToC();
    c.printforce();
}

答案 3 :(得分:0)

如果不确切知道GetXArg()等做了什么,当您致电force[i].convToP();时,您似乎正在修改原始力量。因此,在此循环之后,阵列中的所有力都将转换为极性。如果您只想打印极地和笛卡尔表示而不更改原件,则应生成力的副本:

cout << "Forces in Polar form: " << endl;
for (int i = 0; i < force.size(); ++i)
{
    Force tmpForce = force[i];
    tmpForce.convToP();
    tmpForce.printforce();
}

编辑:看起来@Aconcagua打败了我。