⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filter.cpp

📁 orange源码 数据挖掘技术
💻 CPP
📖 第 1 页 / 共 2 页
字号:
int TValueFilter_string::operator()(const TExample &example) const
{ 
  const TValue &val = example[position];
  if (val.isSpecial())
    return acceptSpecial;

  char *value = caseSensitive ? const_cast<char *>(val.svalV.AS(TStringValue)->value.c_str())
                              : strToLower(val.svalV.AS(TStringValue)->value.c_str());

  char *ref = caseSensitive ? const_cast<char *>(min.c_str()) : strToLower(min);
  
  switch(oper) {
    case Equal:        return TO_BOOL(!strcmp(value, ref));
    case NotEqual:     return TO_BOOL(strcmp(value, ref));
    case Less:         return TO_BOOL(strcmp(value, ref) < 0);
    case LessEqual:    return TO_BOOL(strcmp(value, ref) <= 0);
    case Greater:      return TO_BOOL(strcmp(value, ref) > 0);
    case GreaterEqual: return TO_BOOL(strcmp(value, ref) >= 0);
    case Between:      return TO_BOOL((strcmp(value, ref) >= 0) && (strcmp(value, max.c_str()) <= 0));
    case Outside:      return TO_BOOL((strcmp(value, ref) < 0) && (strcmp(value, max.c_str()) >= 0));
    case Contains:     return TO_BOOL(string(value).find(ref) != string::npos);
    case NotContains:  return TO_BOOL(string(value).find(ref) == string::npos);
    case BeginsWith:   return TO_BOOL(!strncmp(value, ref, strlen(ref)));

    case EndsWith:
      { const int vsize = strlen(value), rsize = strlen(ref);
        return TO_BOOL((vsize >= rsize) && !strcmp(value + (vsize-rsize), ref));
      }

    default:
      return -1;
  }

  if (!caseSensitive) {
    delete value;
    delete ref;
  }
}


TValueFilter_stringList::TValueFilter_stringList()
: TValueFilter(ILLEGAL_INT, -1),
  values(mlnew TStringList()),
  caseSensitive(true)
{}


TValueFilter_stringList::TValueFilter_stringList(const int &pos, PStringList bl, const int &accs, const int &op, const bool csens)
: TValueFilter(pos, accs),
  values(bl),
  caseSensitive(csens)
{}

int TValueFilter_stringList::operator()(const TExample &example) const
{ 
  const TValue &val = example[position];
  if (val.isSpecial())
    return acceptSpecial;

  char *value = caseSensitive ? const_cast<char *>(val.svalV.AS(TStringValue)->value.c_str())
                              : strToLower(val.svalV.AS(TStringValue)->value.c_str());
  char *ref = caseSensitive ? NULL : new char[1024];

  TStringList::const_iterator vi(values->begin()), ve(values->end());
  for(; vi!=ve; vi++)
    if (caseSensitive) {
      if (!strcmp((*vi).c_str(), value))
        break;
    }
    else {
      if ((*vi).size() >= 1024)
        raiseError("reference string too long (1023 characters is the limit)");
      strcpy(ref, (*vi).c_str());
      for(char *i = ref; *i; i++)
        *i = tolower(*i);
      if (!strcmp(ref, value))
        break;
    }

  if (!caseSensitive) {
    delete ref;
    delete value;
  }

  return vi==ve ? 0 : 1;
}


#undef DIFFERENT
#undef LESS_EQUAL
#undef TO_BOOL

TFilter_values::TFilter_values(bool anAnd, bool aneg, PDomain dom)
: TFilter(aneg, dom),
  conditions(mlnew TValueFilterList()),
  conjunction(anAnd)
{}


TFilter_values::TFilter_values(PValueFilterList v, bool anAnd, bool aneg, PDomain dom)
: TFilter(aneg, dom),
  conditions(v),
  conjunction(anAnd)
{}


TValueFilterList::iterator TFilter_values::findCondition(PVariable var, const int &varType, int &position)
{
  if (varType && (var->varType != varType))
    raiseError("invalid variable type");

  checkProperty(domain);

  position = domain->getVarNum(var);
  TValueFilterList::iterator condi(conditions->begin()), conde(conditions->end());
  while((condi!=conde) && ((*condi)->position != position))
    condi++;

  return condi;
}

void TFilter_values::updateCondition(PVariable var, const int &varType, PValueFilter filter)
{
  TValueFilterList::iterator condi = findCondition(var, varType, filter->position);
  if (condi==conditions->end())
    conditions->push_back(filter);
  else
    *condi = filter;
}


void TFilter_values::addCondition(PVariable var, const TValue &val, bool negate)
{
  int position;
  TValueFilterList::iterator condi = findCondition(var, TValue::INTVAR, position);

  TValueFilter_discrete *valueFilter;

  if (condi==conditions->end()) {
    valueFilter = mlnew TValueFilter_discrete(position); // it gets wrapped in the next line
    conditions->push_back(valueFilter);
  }
  else {
    valueFilter = (*condi).AS(TValueFilter_discrete);
    if (!valueFilter)
      raiseError("addCondition(Value) con only be used for setting ValueFilter_discrete");
  }

  if (val.isSpecial())
    valueFilter->acceptSpecial = 1;
  else {
    valueFilter->values->clear();
    valueFilter->values->push_back(val);
  }

  valueFilter->negate = negate;
}


void TFilter_values::addCondition(PVariable var, PValueList vallist, bool negate)
{
  int position;
  TValueFilterList::iterator condi = findCondition(var, TValue::INTVAR, position);

  if (condi==conditions->end())
    conditions->push_back(mlnew TValueFilter_discrete(position, vallist));

  else {
    TValueFilter_discrete *valueFilter = (*condi).AS(TValueFilter_discrete);
    if (!valueFilter)
      raiseError("addCondition(Value) can only be used for setting ValueFilter_discrete");
    else
      valueFilter->values = vallist;
    valueFilter->negate = negate;
  }
}


void TFilter_values::addCondition(PVariable var, const int &oper, const float &min, const float &max)
{
  updateCondition(var, TValue::FLOATVAR, mlnew TValueFilter_continuous(ILLEGAL_INT, oper, min, max));
}


void TFilter_values::addCondition(PVariable var, const int &oper, const string &min, const string &max)
{
  updateCondition(var, STRINGVAR, mlnew TValueFilter_string(ILLEGAL_INT, oper, min, max));
}


void TFilter_values::addCondition(PVariable var, PStringList slist)
{
  updateCondition(var, STRINGVAR, mlnew TValueFilter_stringList(ILLEGAL_INT, slist));
}


void TFilter_values::removeCondition(PVariable var)
{
  int position;
  TValueFilterList::iterator condi = findCondition(var, 0, position);

  if (condi==conditions->end())
    raiseError("there is no condition on value of '%s' in the filter", var->name.c_str());

  conditions->erase(condi);
}
  

bool TFilter_values::operator()(const TExample &exam)
{ checkProperty(domain);
  checkProperty(conditions);

  TExample *example;
  PExample wex;
  if (domain && (domain != exam.domain)) {
    example = mlnew TExample(domain, exam);
    wex = example;
  }
  else
    example = const_cast<TExample *>(&exam);

  PITERATE(TValueFilterList, fi, conditions) {
    const int r = (*fi)->call(*example);
    if ((r==0) && conjunction)
      return negate;
    if ((r==1) && !conjunction)
      return !negate; // if this one is OK, we should return true if negate=false and vice versa
  }

  // If we've come this far; if conjunction==true, all were OK; conjunction==false, none were OK
  return conjunction!=negate;
}

PFilter TFilter_values::deepCopy() const
{
  TValueFilterList *newValueFilters = mlnew TValueFilterList();
  PValueFilterList wnewValueFilters = newValueFilters;

  const_PITERATE(TValueFilterList, vi, conditions) 
    wnewValueFilters->push_back((*vi)->deepCopy());

  TFilter *filter = mlnew TFilter_values(wnewValueFilters,conjunction,negate,domain);
  PFilter wfilter = filter;
  return wfilter;
}


/// Constructor; sets the example
TFilter_sameExample::TFilter_sameExample(PExample anexample, bool aneg)
  : TFilter(aneg, anexample->domain), example(anexample)
  {}


/// Chooses an examples (not) equal to the 'example'
bool TFilter_sameExample::operator()(const TExample &other)
{ return (example->compare(TExample(domain, other))==0)!=negate; }



/// Constructor; sets the example
TFilter_compatibleExample::TFilter_compatibleExample(PExample anexample, bool aneg)
: TFilter(aneg, anexample->domain),
  example(anexample)
{}


/// Chooses an examples (not) compatible with the 'example'
bool TFilter_compatibleExample::operator()(const TExample &other)
{ return example->compatible(TExample(domain, other))!=negate; }




TFilter_conjunction::TFilter_conjunction()
: filters(mlnew TFilterList())
{}


TFilter_conjunction::TFilter_conjunction(PFilterList af)
: filters(af)
{}

bool TFilter_conjunction::operator()(const TExample &ex)
{
  if (filters)
    PITERATE(TFilterList, fi, filters)
      if (!(*fi)->call(ex))
        return negate;

  return !negate;
}


TFilter_disjunction::TFilter_disjunction()
: filters(mlnew TFilterList())
{}


TFilter_disjunction::TFilter_disjunction(PFilterList af)
: filters(af)
{}


bool TFilter_disjunction::operator()(const TExample &ex)
{
  if (filters)
    PITERATE(TFilterList, fi, filters)
      if ((*fi)->call(ex))
        return !negate;

  return negate;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -