用C++写数学(二):不等式

前言

所谓不等式,就是用不等号(<,>,≥,≤,≠)连接的式子(来自百度)
因为 ≠ (懒)(得)(去)(做)。
这里实现了支持以下形态不等式的一个类。

  1. x > 1
  2. x < 5
  3. x ≥ 0
  4. x ≤ 10
  5. 0 < x ≤ 10
    差不多就这样,输出不会出现 0 < x 、 0 > x之类的情况。

功能

1.初始化
2.重设 & get set系列
3.复制移动
4.检测数值是否在不等式内
5.== 与 != 比较两个不等式
6.输出
7.转换成string/LPSTR(char*)/LPCSTR(const char*)

待添功能

1.输入(重点)
2.解不等式组(很实用!!!)
3.大于小于比较两个不等式(平均比较)

示例源码

#include <iostream>
#include <sstream>
#include <string>
#include <stdexcept>
using namespace std;

#define RG_CMP_TYPE int //这。。是一个兼容双构造的类型宏。。 
#define RANGE_UNK_MAX 8 //未知数字符串最长值 

template <typename MIN_T=short,typename MAX_T=short>
//这是一个模板类,因此带来了不少麻烦。。。
class RANGE {  
 private:
  MIN_T min;
  MAX_T max;
  bool hasMin;
  bool hasMax;
  
  bool reachMin; //是否可以等于? 
  bool reachMax;
  
  string unk; //未知数名称 
  public:
   RANGE(const char* max1_min0,RG_CMP_TYPE min_or_max,bool _reachIt,const string _unk=string("x"))
  {        //只要最大值填"1",只要最小值填"0" 
  //以避免ambious(重载抉择)问题,我把首参数类型改成const char* 
   if(max1_min0 == "1")
   {
    hasMax = true;
    hasMin = false;
    max = (MAX_T)min_or_max;
    reachMax = _reachIt;
   }else if(max1_min0 =="0")
   {
    hasMin = true;
    hasMax = false;
    min = (MIN_T)min_or_max;
    reachMin = _reachIt;
   }
   unk = _unk;
   fresh(); 
  }
   //最大值最小值都有的时候用这个构函↓
   RANGE(MIN_T _min,bool _rchMin,
         MAX_T _max,bool _rchMax,
         const string _unk=string("x"))
  : //init list
   min{_min} , reachMin{_rchMin} , 
   max{_max} , reachMax{_rchMax} , 
   unk{_unk}
  {
    /*if(_min == -INFINITE)
       hasMin=false;
             else
                hasMin=true; 
                if(_max == INFINITE)
       hasMax=false;
             else
                hasMax=true;*/
                hasMax=true;
                hasMin=true;
    fresh();
  }
  RANGE(RANGE &&src) // Move constructor(这些都是书上照搬的)
  {//不用冒号式赋初值法。原因:太长看得不爽。 
    min = move(src.min);
    max = move(src.max);
    hasMin = move(src.hasMin); 
    hasMax = move(src.hasMax); 
    reachMin = move(src.reachMin); 
    reachMax = move(src.reachMax);
    unk = move(src.unk); 
    fresh();  
  }
  RANGE(const RANGE& src)// Copy constructor
  {
   min = src.min;
    max = src.max;
    hasMin = src.hasMin; 
    hasMax = src.hasMax; 
    reachMin = src.reachMin; 
    reachMax = src.reachMax;
    unk = src.unk; 
    fresh(); 
  }
   RANGE() = default; //Default constructor
   ~RANGE() = default; //Destructor
    //一串get set ↓ 
  MIN_T  get_min(void){return min;   }
  MAX_T  get_max(void){return max;   }
  MIN_T  set_min(MIN_T _min){return min = _min;  }
  MAX_T  set_max(MAX_T _max){return max = _max;  }
  bool  get_reachMin(void){return reachMin;  }
  bool  get_reachMax(void){return reachMax;  }
  bool  set_reachMin(bool _rchMin){return reachMin = _rchMin;  }
  bool  set_reachMax(bool _rchMax){return reachMax = _rchMax;  }
  bool  get_hasMin(void){return hasMin;   }
  bool  get_hasMax(void){return hasMax;   }
  bool  set_hasMin(bool _hasMin){return _hasMin = hasMin;   }
  bool  set_hasMax(bool _hasMax){return _hasMax = hasMax;   }
  string get_unk(void){ return unk;   }
  string set_unk(const string _unk){ return _unk = unk;   }
  char* get_unk_str(void){return (char *)unk.c_str();  }
  char* set_unk_str(char* str){return LPSTR((unk = str).c_str()); }
  const char* get_unk_c_str(void){return unk.c_str();  }
  const char* set_unk_c_str(const char* str){return (unk = str).c_str(); }
 char* set(const char* max1_min0,RG_CMP_TYPE min_or_max,bool _reachIt,const string _unk=string("x"))
  { //我想表达reset的意思。
   if(max1_min0 == "1")
   {
    hasMax = true;
    hasMin = false;
    max = (MAX_T)min_or_max;
    reachMax = _reachIt;
   }else if(max1_min0 =="0")
   {
    hasMin = true;
    hasMax = false;
    min = (MIN_T)min_or_max;
    reachMin = _reachIt;
   }
   unk = _unk;
   fresh(); 
   return shape_str();
  }
char* set(MIN_T _min,bool _rchMin,
          MAX_T _max,bool _rchMax,
          const string _unk=string("x"))
  { //overload
   min = _min;
   max = _max;
   reachMin = _rchMin;
   reachMax = _rchMax;
   unk = _unk;  //Only Constructor can use init list.
                hasMax=true;
                hasMin=true;
    fresh();
    return shape_str();
  }
 void fresh(void)
 { //再次原谅我的无知,我想表达refresh的意思。。。
  if((hasMax && hasMin) && min > max)
  {
   throw logic_error(string("RANGE ERROR: Min Value > Max Value!!!"));
  }
  if(!hasMax && !hasMin)
  {
   throw logic_error(string("RANGE ERROR: Neither max value nor min value!"));
  }
  if(unk.size() == 0)
  {
   throw logic_error(string("RANGE ERROR: Unknown letter(s) mustn't be empty!"));
  }else if(unk.size() > RANGE_UNK_MAX)
  {
            throw logic_error(string("RANGE ERROR: Unknown letters exceed the scope!(too long)"));
  }
 }
template <typename _T>
 bool can_be(_T tstValue)
 { //通俗易懂的函数名。。有点过分。。
  if((!hasMax) && hasMin)
  {
   if((reachMin && tstValue >= min)||((!reachMin) && tstValue > min))
     return true;
         return false;
  }
  else if((!hasMin) && hasMax)
  {
   if((reachMax && tstValue <= max)||((!reachMax) && tstValue < max))
     return true;
         return false;
  }
  else if(((reachMin && tstValue >= min)||((!reachMin) && tstValue > min))
     && ((reachMax && tstValue <= max)||((!reachMax) && tstValue < max)))
     {
      return true;
  }
  return false;
 }
 ostream& print(ostream &out=cout)
 {
      if(hasMin && hasMax)
      {
        out<<min;
        out<<(reachMin ? "≤" : "<");
   }  
      out<<unk; //自身未知数 
      if(hasMax)
           out<<(reachMax ? "≤" : "<");
         else if(hasMin)
              out<<(reachMin ? "≥" : ">");
         if(hasMax)
            out<<max;
         else
            out<<min;
      return out;
 } 
 ostream& print(const char* unk,ostream &out=cout)
 {
      if(hasMin && hasMax)
      {
        out<<min;
        out<<(reachMin ? "≤" : "<");
   }    
      out<<unk; //临时指定 
      if(hasMax)
           out<<(reachMax ? "≤" : "<");
         else if(hasMin)
              out<<(reachMin ? "≥" : ">");
      if(hasMax)
            out<<max;
         else
            out<<min;
      return out;
    }
 ostream &write(ostream &out=cout)
 {
     return print(out);
 }
 friend ostream &operator <<(ostream &outs,RANGE<MIN_T,MAX_T> &rg)
    //ostream &RANGE<MIN_T,MAX_T>::operator <<(ostream &outs=cout,class RANGE<MIN_T,MAX_T> &rg)
 {
         if(rg.hasMin && rg.hasMax)
      {
        outs<<rg.min;
        outs<<(rg.reachMin ? "≤" : "<");
   }    
      outs<<rg.unk;
      if(rg.hasMax)
           outs<<(rg.reachMax ? "≤" : "<");
         else if(rg.hasMin)
              outs<<(rg.reachMin ? "≥" : ">");
      if(rg.hasMax)
            outs<<rg.max;
         else
            outs<<rg.min;
       return outs;
  }
  /* ### 未实现
  #define _404(iter) (iter == s.npos) 
  void read(string s)
  {
   auto _less = s.find_first_of("<"); //英文风格 
     auto _more = s.find_first_of(">");
     auto _less2 = s.find_first_of("<"); //中文风格 
     auto _more2 = s.find_first_of(">");
     auto _less_rch = s.find_first_of("≤");//只有中文风格 
     auto _more_rch = s.find_first_of("≥");
     if(_404(_less) && _404(_more) && _404(_less2) && _404(_more2) && _404(_less_rch) && _404(_more_rch))
     {
      SetLastError(13); //"数据无效" 
      return; //404
  }else{
      //这儿还在施工呢。
   return;
  }
  }
    friend istream &operator >>(istream &ins,RANGE<MIN_T,MAX_T> &rg)
    {//哎呀呀,可恶的“左值绑定失败”的错误!我加了const没一点用。
     string s;
     ins>>s;
     read(s);
  return ins;
 }*/
 string shape(void)
 {
  stringstream ss;//字符串流还是挺实用的
  if(hasMin && hasMax)
      {
        ss<<min;
        ss<<(reachMin ? "≤" : "<");
   }    
      ss<<unk;
      if(hasMax)
           ss<<(reachMax ? "≤" : "<");
         else if(hasMin)
              ss<<(reachMin ? "≥" : ">");
      if(hasMax)
            ss<<max;
         else
            ss<<min;
  return ss.str();
 }
 char* shape_str(void)
 {
  return (char*)this ->shape().c_str();
 }
 const char* shape_c_str(void)
 {
  return this ->shape().c_str();
 }
 bool operator == (RANGE &rg) { return this->shape() == rg.shape(); } //比较他们的写法是最简单的方法。 
 bool operator != (RANGE &rg) { return this->shape() != rg.shape(); } //可能因为未重载,不能使用char* || const char* 
 /*本品暂不支持大于小于比较功能。*/
};
int main() //主函数
{
 RANGE <> rg1("0",13,true),
          rg2("1",5,false),
          rg3(0,true,10,true),
    cout<<"Range 1:"<<rg1.shape_c_str();
    //注意!cout必须分开输出,否则会导致不知名的共用变量Bug! 
 cout<<"\nRange 2:"<<rg2.shape_str();
 cout<<"\nRange 3:"<<rg3<<endl; //直接拼接亦可。 
    cout<<"In Range 3,Value -1 can be in it? "<<boolalpha<<rg3.can_be(-1)<<endl;
    cout<<"Range 1"<<(rg1 == rg2 ? " equals " : " doesn't equal ")<<"equals to Range 2."<<endl;
    //...
    return 0;
}

虽然没有什么实际价值,但是很有成就感!!!
其实也是有价值的,在以后的一些数学类(ToBeContinued) 用上它多好!
我关于模板、类不是很熟练,但相比 一窍不通的算法及狗屁不通的指针 来说好多了:)
.
示例输出
Range 1:x≥13
Range 2:x<5
Range 3:0≤x≤10
In Range 3,Value -1 can be in it? false
Range 1 doesn’t equal to Range 2.

达到了预期的效果。
如果试出来还有BUG(s)一定要留言哦!

下期预告

有了不等式,我还没打算设计 单项式、多项式、方程、等式 之类的鬼东西,但是有心设计比较实用的几个函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值