前言
所谓不等式,就是用不等号(<,>,≥,≤,≠)连接的式子(来自百度)
因为 ≠ 不(懒)太(得)常(去)用(做)。
这里实现了支持以下形态不等式的一个类。
- x > 1
- x < 5
- x ≥ 0
- x ≤ 10
- 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)一定要留言哦!
下期预告
有了不等式,我还没打算设计 单项式、多项式、方程、等式 之类的鬼东西,但是有心设计比较实用的几个函数。