如何创建一个不同大小的数组作为私有类变量?

时间:2014-06-09 17:51:57

标签: c++

我试图创建一个从用户那里获取多项式函数的程序,计算它拥有的术语数量,创建一个足以存储所有术语的数组,然后将术语存储在那里。问题是,我不太确定如何在程序确定函数的大小之后添加私有类变量(或更具体地说,字符串数组)。我需要这个字符串数组是一个私有类变量,因为我希望能够通过其他类方法访问它的内容,例如,cout每个函数术语。

main.cpp中:

#include <iostream>
#include <string>
#include "Function.h"
using namespace std;

int main()
{
    Function func1;
    func1.coutFuncTerms();
    func1.coutFunc();
    return 0;
}

Function.h:

#ifndef FUNCTION_H
#define FUNCTION_H

#include <iostream>
#include <string>
#include "Function.h"
using namespace std;

class Function
{
    public:
        Function();
        ~Function();
        void removePlus(string*);
        void removeWhitespace(string*);
        void setFuncTerms();
        void splitTerms();
        void coutFuncTerms();
        void coutFunc();
        void coutTerms(string);
    protected:
    private:
        string func;
        int funcTerms;
};

#endif

Function.cpp:

#include <iostream>
#include <string>
#include "Function.h"
using namespace std;

// Function Constructor
//
// Stores a function inputted by the user
// Adds a null character ('\0') to the end of a string
// Erases a redundant '+' sign at the beginning of a string if there's one there
// Erases any whitespace characters in a string
// Stores the number of terms in the function
Function::Function()
{
    getline(cin, func);
    setFuncTerms();
    //splitTerms();
}

Function::~Function()
{

}

// removePlus Function
//
// Erases a redundant '+' sign at the beginning of a string if there's one there
void Function::removePlus(string* func)
{
    if(func->at(0) == '+')
    {
        func->erase(0, 1);
    }
}

// removeWhitespace Function
//
// Erases any whitespace characters in a string
void Function::removeWhitespace(string* func)
{
    for(int x = 0; unsigned(x) < func->length() - 1; x++)
    {
        while(func->at(x) == ' ' || func->at(x) == '\t')
        {
            func->erase(x, 1);
        }
    }
}

// setFuncLength Function
//
// Finds the number of terms in a Function object's 'func' variable
// Assigns this number to the object's 'funcLength' variable
void Function::setFuncTerms()
{
    funcTerms = 0;
    for(int funcTerm = 0; unsigned(funcTerm) < func.length(); funcTerm += 1)
    {
        bool isAPotentialTerm = false;
        bool isATrueTerm = false;
        if(func.at(funcTerm) == '+' || func.at(funcTerm) == '-')
        {
            isAPotentialTerm = true;
        }
        if(isAPotentialTerm == true)
        {
            for(int newFuncTerm = funcTerm + 1; unsigned(newFuncTerm) < func.length(); newFuncTerm += 1)
            {
                if(func.at(newFuncTerm) == '+' || func.at(newFuncTerm) == '-')
                {
                    break;
                }
                if(func.at(newFuncTerm) != ' ' && func.at(newFuncTerm) != '\t')
                {
                    isATrueTerm = true;
                    break;
                }
            }
        }
        if(isATrueTerm)
        {
            funcTerms++;
        }
    }
}

// splitTerms Function
//
// Calls the splitTerm function for each term in 'func' according to the function array 'funcArray'
void Function::splitTerms()
{
    string funcArray[funcTerms];
    int tempFuncLength = 0;
    for(int funcTerm = 0; unsigned(funcTerm) < func.length(); funcTerm += 1)
    {
        bool isAPotentialTerm = false;
        bool isATrueTerm = false;
        if(func.at(funcTerm) == '+' || func.at(funcTerm) == '-')
        {
            isAPotentialTerm = true;
        }
        if(isAPotentialTerm == true)
        {
            for(int newFuncTerm = funcTerm + 1; unsigned(newFuncTerm) < func.length(); newFuncTerm += 1)
            {
                if(func.at(newFuncTerm) == '+' || func.at(newFuncTerm) == '-')
                {
                    break;
                }
                if(func.at(newFuncTerm) != ' ' && func.at(newFuncTerm) != '\t')
                {
                    isATrueTerm = true;
                    break;
                }
            }
        }
        if(isATrueTerm)
        {
            string temp;
            for(; unsigned(funcTerm) < func.length() && func.at(funcTerm) != '+' && func.at(funcTerm) != '-'; funcTerm += 1)
            {
                funcArray[tempFuncLength].append(1, func.at(funcTerm));
            }
            tempFuncLength++;
        }
    }
    for(int x = 0; x < funcTerms; x++)
    {
        cout << "Term " << x + 1 << " is: " << funcArray[x] << endl;
    }
}

void Function::coutFuncTerms()
{
    cout << "Terms: " << funcTerms << endl;
}

void Function::coutFunc()
{
    cout << "Function: " << func << endl;
}

void Function::coutTerms(string funcArrayTerm)
{
    /*for(int x = 0; x < funcLength; x++)
    {
        cout << "Term " << x << " is: " << funcArray[x] << endl;
    }*/
    //cout << funcArray[0] << endl;
}

1 个答案:

答案 0 :(得分:1)

我强烈建议你改变你的设计。

功能 terms 的容器。所以让我们定义一个术语

术语最低限度为系数和指数:

struct Fundamental_Term
{
  double coefficient;
  int    exponent;
};

如果您的功能只是一个变量,那么您需要的只是Fundamental_Term。否则,您需要具有基本变量名称:

struct Term_With_Base
: public Fundamental_Term
{
  std::string variable_name;
};

注意:如果您无法使用继承,请将Fundamental_Term的成员变量复制到Term_With_Base

请记住,功能是术语的集合或容器。假设一个具有多个基数的函数,我们可以声明:

struct Function
{
  std::vector<Term_With_Base> terms;
};

条款评估
要评估函数f(x),必须评估所有项并将它们的结果相加。 这分解为两个要求:1)术语必须有评估方法; 2)函数类必须具有对术语求和的求值方法。

因此,我们在基类中添加了一个评估函数:

struct Fundamental_Term
{
  double coefficient;
  int exponent;
  double evaluate(double value)
  {
    return coefficient * pow(value, exponent);
  }
};

struct Function
{
  std::vector<Term_With_Base> terms;
  double evauate(double value)
  {
    const unsigned int quantity = terms.size();
    double result = 0.0;
    for (unsigned int i = 0; i < quantity; ++i)
    {
      result = result + terms[i].evaluate(value);
    }
    return result;
   }
};

从字符串创建函数时,首选项是创建Fundamental_Term的构造函数,该构造函数接受字符串参数。术语对象应该读取其系数,变量名称和指数,而不是函数容器。

有关更多示例,请搜索StackOverflow以获取“c ++解析术语评估”。

编辑1:插入字词
插入术语的一种方法是在术语数据结构中使用从字符串加载术语的方法:

bool
Fundamental_Term ::
load_from string(const std::string& input,
                 unsigned int &     start_position)
{
  bool term_is_valid = false;
  // Parse the string and load appropriate fields.
  // Set the start position to the first position after the valid term.
  // Set term_is_valid to true if the term has valid syntax.
  return term_is_valid;
}

Function对象将有一个成员从字符串加载术语。

bool
Function ::
load_terms_from_string(const std::string& input)
{
  Term_With_Base term;
  unsigned int   position_in_string = 0;
  bool           term_is_valid = true;
  while (term_is_valid && (position_in_string < input.size()))
  {
    term_is_valid = term.load_from_string(input, position_in_string);
    if (term_is_valid)
    {
      terms.push_back(term);
    }
  }
}

用于包含术语的std::vector将根据需要随每个解析的附加术语进行扩展。解析字符串或存在无效术语时,循环将终止。