如何设置循环遍历可能的向量 table 元素

How to set up a loop that iterates over possible vector table elements

该程序与等差数列有关。我的程序安排了这些用于索引的常量

用户应输入上述 5 个字符中的 3 个,后跟对每个字符有意义的双精度值。

例如:
如果用户输入:

t 3.6 f 1.1 l 1.3

T 3.6 F 1.1 L 1.3

用户应该收到

的输出
I 0.1 N 3

这是因为用户给出了定义为常量的 5 个选项中的 3 个

我已经定义了函数来回答用户输入所需的所有情况。我用前 3 个字母作为给定字母,最后两个字母作为未知字母来标记每个函数名称。对于上面的示例,调用 void fltin(vector<double> & v, vector<bool> & k) 将输出 IN。 (2 个案例已被豁免,我创建了一个功能让用户知道这些案例是否会出现在下面)

另一个例子: 调用 filnt(vector<double> & v, vector<bool> & k) 表示用户正在提供 FIL 的值。输出应为 NT.

我的问题: 我在给定用户输入(不区分大小写)的最后步骤遇到问题,我可以在 TABLE 中调用正确的向量元素。我想使用布尔类型的向量来控制它。

感谢所有帮助。

#include <iostream>
#include <vector>
#include <cmath>
#include <cstdlib>
#include <string>
using namespace std;
const unsigned F = 0, I = 1, L = 2, N = 3, T = 4;
bool die(const string & msg);
void filnt(vector<double> & v, vector<bool> & k) {
    v[T] = v[F];
    for (double i = (v[F] + v[I]); i <= (v[L] + v[I]); i += v[I]) {
        v[T] += i;
    }
    cout << "T:" << v[T] << " ";
    v[N] = (2 * v[T]) / (v[F] + v[L]);
    cout << "N:" << v[N] << endl;
}
void finlt(vector<double> & v, vector<bool> & k) {
    v[L] = v[F];
    for (double i = 1; i < v[N]; i++) {
        v[L] += v[I];
    }
    cout << "L:" << v[L] << " ";

    v[T] = v[F];
    for (double i = (v[F] + v[I]); i <= (v[L]); i += v[I]) {
        v[T] += i;
    }
    cout << "T:" << v[T] << endl;
}

void fitln(vector<double> & v, vector<bool> & k) {
    bool die("not checking this condition");
}

void flnit(vector<double> & v, vector<bool> & k) {
    v[I] = (v[L] - v[F]) / (v[N] - 1);
    cout << "I:" << v[I] << " ";
    v[T] = v[F];
    for (double i = (v[F] + v[I]); i <= (v[L] + v[I]); i += v[I]) {
        v[T] += i;
    }
    cout << "T:" << v[T] << endl;
}

void fltin(vector<double> & v, vector<bool> & k) {
    v[N] = (2 * v[T]) / (v[F] + v[L]);
    cout << "N:" << v[N] << " ";
    v[I] = (v[L] - v[F]) / (v[N] - 1);
    cout << "I:" << v[I] << endl;
}

void ftnil(vector<double> & v, vector<bool> & k) {
    v[L] = ((2 * v[T]) / v[N]) - v[F];
    cout << "L:" << v[L] << " ";
    v[I] = (v[L] - v[F]) / (v[N] - 1);
    cout << "I:" << v[I] << endl;
}

void iltfn(vector<double> & v, vector<bool> & k) {
    bool die("not checking this condition");
}
void ilnft(vector<double> & v, vector<bool> & k) {
    v[F] = v[L];
    for (double i = 1; i < v[N]; i++) {
        v[F] -= v[I];
    }
    cout << "F:" << v[F] << " ";
    v[T] = v[F];
    for (double i = (v[F] + v[I]); i <= (v[L]); i += v[I]) {
        v[T] += i;
    }
    cout << "T:" << v[T] << endl;
}

void itnfl(vector<double> & v, vector<bool> & k) {
    v[F] = ((v[T] * (2 / v[N])) - ((v[N] - 1)*v[I])) / 2;
    cout << "F:" << v[F] << " ";
    v[L] = ((2 * v[T]) / v[N]) - v[F];
    cout << "L:" << v[L] << endl;
}

void lntfi(vector<double> & v, vector<bool> & k) {
    v[F] = ((2 * v[T]) / v[N]) - v[L];
    cout << "F:" << v[F] << " ";
    v[I] = (v[L] - v[F]) / (v[N] - 1);
    cout << "I:" << v[I] << endl;
}

struct FD { 
    double k1; 
    double k2; 
    double k3;
    double uk1;
    double uk2;
    void(*f)(vector<double> &, vector<bool> &); 
};

const vector<FD> TABLE = {
{F,I,L,N,T,filnt},
{F,I,N,L,T,finlt},
{F,L,N,I,T,flnit},
{F,L,T,I,N,fltin},
{F,T,N,I,L,ftnil},
{I,L,N,F,T,ilnft},
{I,T,N,F,L,itnfl},
{L,N,T,F,I,lntfi}
};


int main() {
    vector<double> v(5);
    vector<bool> k = { false, false, false, false, false };
    char cone;
    char ctwo;
    char cthree;
    double one;
    double two;
    double three;
    cin >> cone;
    cin >> one;
    cin >> ctwo;
    cin >> two;
    cin >> cthree;
    cin >> three;
    // for loop I am having trouble constructing 
    /*

    */
}
bool die(const string & msg) {
    cout << "Fatal Error:" << msg << endl;
    exit(EXIT_FAILURE);
}

所以,总结一下,你的问题是你想根据用户输入的三个字符调用一个函数。

没有非常聪明的方法可以做到这一点。特别是你不能以某种方式将你选择的函数名称用于调用哪个函数的逻辑中。所以你应该放弃编码函数名称,并选择实际描述函数功能的名称。

可能最好的方法是从三个字母代码到函数(也许到 vector<bool>,我不太明白那一点)。

#include <string>
#include <vector>
#include <map>

typedef void (*function)(std::vector<double>&, std::vector<bool>&);
std::map<std::string, function> table{{"fil", filnt}, {"fin", finlt}, ... };

然后你只需要根据三个字母代码查找要调用的函数。

std::string code{cone, ctwo, cthree}; // make three letter code
table[code](v, k); // call appropriate function

未经测试的代码,您还应该为无效输入添加一些错误检查。

您可以创建地图

void assign(std::vector<double>& v, std::vector<bool>& flags, char c, double value)
{
    switch (c)
    {
        case 'F': case 'f': v[F] = value; flags[F] = true; break;
        case 'I': case 'i': v[I] = value; flags[I] = true; break;
        case 'L': case 'l': v[L] = value; flags[L] = true; break;
        case 'N': case 'n': v[N] = value; flags[N] = true; break;
        case 'T': case 't': v[T] = value; flags[T] = true; break;
    }
}

int main()
{
    vector<double> v(5);
    vector<bool> flags = { false, false, false, false, false };
    for (int i = 0; i != 3; ++i) {
        char c;
        double value;
        std::cin >> c >> value;
        assign(v, flags, c, value);
    }
    const std::map<std::vector<bool>, void(*)(std::vector<double> &)> m = {
        {{true, true, true, false, false}, filnt},
        {{true, true, false, true, false}, finlt},
        {{true, false, true, true, false}, flnit},
        {{true, false, true, false, true}, fltin},
        {{true, false, false, true, true}, ftnil},
        {{false, true, true, true, false}, ilnft},
        {{false, true, false, true, true}, itnfl},
        {{false, false, true, true, true}, lntfi}
    };
    auto it = m.find(flags);
    if (it == m.end()) {
        std::cout << "Fatal Error: not checking this condition\n";
        return EXIT_FAILURE;
    }
    it->second(v);
}

Demo