条件组合计算模型

    结合STL采用排序+回溯. 目前支持windows平台, 但可稍作修改移植到Linux.

  1. /********************************************************************
  2.     created:     2008/11/09
  3.     created:     9:11:2008   16:07
  4.     filename:   CConditionCombination.h
  5.     file path:  
  6.     file base:   CConditionCombination
  7.     file ext:     h
  8.     author:     rawman
  9.     email:       rawman_9527@sina.com
  10.     
  11.     purpose:    This module is designed to calculate a kind of condit-
  12.                 ionally mathematic combination, in which each result  
  13.                 group's key sum equals(or mostly equals) to the condi-
  14.                 tional value given.
  15.     
  16.     attention:  The following parameter KEYTYPE can be integer , sin-
  17.                 gle or double data type, don't forget to set the Comp-
  18.                 arePrecision if KEYTYPE is float or double, the Compa-
  19.                 rePrecision should not be minus, besides that you can 
  20.                 also set the ComparePrecision to get the region group-
  21.                 s if KEYTYPE is integer
  22. *********************************************************************/
  23. #ifndef __CCONDITIONCOMBINATION_H__
  24. #define __CCONDITIONCOMBINATION_H__
  25. #include <Windows.h>
  26. #include <map>
  27. #include <vector>
  28. namespace ConditionCombination
  29. {
  30.     template<typename KEYTYPE, typename DATATYPE>
  31.     class CConditionCombination
  32.     {
  33.     public:
  34.         CConditionCombination(std::multimap<KEYTYPE, DATATYPE>& DataMap, KEYTYPE ConditionValue);
  35.         CConditionCombination(KEYTYPE ConditionValue);
  36.     public:
  37.         // the following functions just operate an element in the DataSource
  38.         bool InsertAnElement(IN KEYTYPE Key, IN const DATATYPE& Data);
  39.         bool RemoveAnElement(IN KEYTYPE Key);                               
  40.         bool ModifyAnElement(IN KEYTYPE Key, IN const DATATYPE& Data);
  41.         // to calculate the result
  42.         void Make(OUT std::vector<std::multimap<KEYTYPE, DATATYPE> >& Result);
  43.         // to set ComparePrecision
  44.         void SetCmpPrecision(IN KEYTYPE ComparePrecision);
  45.     private:
  46.         std::multimap<KEYTYPE, DATATYPE> m_mmapData;    // DataSource
  47.         KEYTYPE m_ktConditionValue;                     // conditional value
  48.         KEYTYPE m_ktCmpPrecision;                       // ComparePrecision
  49.     };
  50.     template<typename KEYTYPE, typename DATATYPE>
  51.     CConditionCombination<KEYTYPE, DATATYPE>::CConditionCombination(std::multimap<KEYTYPE, DATATYPE>& DataMap, KEYTYPE ConditionValue)
  52.         : m_mmapData(DataMap)   
  53.         , m_ktConditionValue(ConditionValue)
  54.         , m_ktCmpPrecision(0)
  55.     {
  56.     }
  57.     template<typename KEYTYPE, typename DATATYPE>
  58.     CConditionCombination<KEYTYPE, DATATYPE>::CConditionCombination(KEYTYPE ConditionValue)
  59.         : m_ktConditionValue(ConditionValue)
  60.         , m_ktCmpPrecision(0)
  61.     {
  62.     }
  63.     template<typename KEYTYPE, typename DATATYPE>
  64.     bool CConditionCombination<KEYTYPE, DATATYPE>::InsertAnElement(IN KEYTYPE Key, IN const DATATYPE& Data)
  65.     {
  66.         std::pair<std::multimap<KEYTYPE, DATATYPE>::iterator, bool> pairRet;
  67.         pairRet = m_mmapData.insert(std::make_pair(Key, Data));
  68.         return pairRet.second;
  69.     }
  70.     template<typename KEYTYPE, typename DATATYPE>
  71.     bool CConditionCombination<KEYTYPE, DATATYPE>::RemoveAnElement(IN KEYTYPE Key)
  72.     {
  73.         std::multimap<KEYTYPE, DATATYPE>::iterator iter;
  74.         iter = m_mmapData.find(Key);
  75.         if(iter == m_mmapData.end())
  76.         {
  77.             return false;
  78.         }
  79.         
  80.         m_mmapData.erase(iter);
  81.         return true;
  82.     }
  83.     template<typename KEYTYPE, typename DATATYPE>
  84.     bool CConditionCombination<KEYTYPE, DATATYPE>::ModifyAnElement(IN KEYTYPE Key, IN const DATATYPE& Data)
  85.     {
  86.         std::multimap<KEYTYPE, DATATYPE>::iterator iter;
  87.         iter = m_mmapData.find(Key);
  88.         if(iter == m_mmapData.end())
  89.         {
  90.             return false;
  91.         }
  92.         iter->second = Data;
  93.         return true;
  94.     }
  95.     template<typename KEYTYPE, typename DATATYPE>
  96.     void CConditionCombination<KEYTYPE, DATATYPE>::Make(OUT std::vector<std::multimap<KEYTYPE, DATATYPE> >& Result)
  97.     {
  98.         KEYTYPE Sum = 0;    // to use in calculating key sum
  99.         std::multimap<KEYTYPE, DATATYPE>::iterator iter = m_mmapData.begin();
  100.         std::vector<std::multimap<KEYTYPE, DATATYPE>::iterator> vecAGroupPtr;   // to use in geting a respected group
  101.         while(true)
  102.         {
  103.             // the iterator has moved to the last, 
  104.             // it cannot move forward any more and must to check whether it can trace back to the last step
  105.             while(iter == m_mmapData.end())
  106.             {
  107.                 if(vecAGroupPtr.size() == 0)    // no steps can be traced to
  108.                 {
  109.                     return;
  110.                 }
  111.                 // trace back to the last step
  112.                 iter = vecAGroupPtr[vecAGroupPtr.size() - 1];
  113.                 Sum -= iter->first;
  114.                 vecAGroupPtr.pop_back();
  115.                 iter++;
  116.             }
  117.             if(Sum + iter->first + m_ktCmpPrecision < m_ktConditionValue)           // if has no cmpprecision, it should be: Sum + iter->first < m_ktConditionValue
  118.             {
  119.                 vecAGroupPtr.push_back(iter);
  120.                 Sum += iter->first;
  121.             }
  122.             else if( (Sum + iter->first - m_ktCmpPrecision <= m_ktConditionValue)
  123.                 && (Sum + iter->first + m_ktCmpPrecision >= m_ktConditionValue) )  
  124.              // if has no cmpprecision, it should be: Sum + iter->first == m_ktConditionValue    
  125.             {
  126.                 std::multimap<KEYTYPE, DATATYPE> mmapAGroup;
  127.                 
  128.                 for(size_t i = 0; i < vecAGroupPtr.size(); i++)
  129.                 {
  130.                     mmapAGroup.insert(std::make_pair(vecAGroupPtr[i]->first, vecAGroupPtr[i]->second));
  131.                 }
  132.                 mmapAGroup.insert(std::make_pair(iter->first, iter->second));
  133.                 Result.push_back(mmapAGroup);
  134.             }
  135.             else    // if has no cmpprecision, here means: Sum + iter->first > m_ktConditionValue
  136.             {
  137.                 if(vecAGroupPtr.size() > 0)
  138.                 {
  139.                     Sum -= vecAGroupPtr[vecAGroupPtr.size() - 1]->first;
  140.                     iter = vecAGroupPtr[vecAGroupPtr.size() - 1];
  141.                     vecAGroupPtr.pop_back();
  142.                 }
  143.                 else    // if has no cmpprecision, here means: Sum == 0 && iter->first > m_ktConditionValue
  144.                            // do not need to calculate any more because after the iterator (include) any element's key value  has exceeded the conditional value within precision
  145.                 {
  146.                     break;   
  147.                 }
  148.             }
  149.             iter++;
  150.         }   // while(true)
  151.     }
  152.     template<typename KEYTYPE, typename DATATYPE>
  153.     void CConditionCombination<KEYTYPE, DATATYPE>::SetCmpPrecision(IN KEYTYPE ComparePrecision)
  154.     {
  155.         m_ktCmpPrecision = ComparePrecision;
  156.     }
  157. // namespace ConditionCombination
  158. #endif

    该模型的使用演示:

  1. #include "CConditionCombination.h"
  2. #include <iostream>
  3. #include <string>
  4. using namespace ConditionCombination;
  5. void Display(std::vector<std::multimap<int, std::string> >& Result)
  6. {
  7.     for(size_t i = 0; i < Result.size(); i++)
  8.     {
  9.         for(std::multimap<int, std::string>::iterator iter = Result[i].begin();
  10.             iter != Result[i].end(); iter++)
  11.         {
  12.             std::cout<<"("<<iter->first<<","<<iter->second<<")"<<" ";
  13.         }
  14.         
  15.         std::cout<<std::endl;
  16.     }
  17.     
  18.     std::cout<<std::endl;
  19. }
  20. int main(int argc, char* argv[])
  21. {
  22.     std::multimap<int, std::string> MyMap;
  23.     MyMap.insert(std::make_pair(14, "String1"));
  24.     MyMap.insert(std::make_pair(12, "String2"));
  25.     MyMap.insert(std::make_pair(12, "String3"));
  26.     MyMap.insert(std::make_pair(14, "String4"));
  27.     MyMap.insert(std::make_pair(14, "String5"));
  28.     MyMap.insert(std::make_pair(10, "String6"));
  29.     MyMap.insert(std::make_pair(14, "String7"));
  30.     MyMap.insert(std::make_pair(10, "String8"));
  31.     MyMap.insert(std::make_pair(12, "String9"));
  32.     MyMap.insert(std::make_pair(12, "String10"));
  33.     MyMap.insert(std::make_pair(10, "String11"));
  34.     MyMap.insert(std::make_pair(12, "String12"));
  35.     MyMap.insert(std::make_pair(12, "String13"));
  36.     MyMap.insert(std::make_pair(8, "String14"));
  37.     MyMap.insert(std::make_pair(6, "String15"));
  38.     MyMap.insert(std::make_pair(7, "String16"));
  39.     MyMap.insert(std::make_pair(5, "String17"));
  40.     MyMap.insert(std::make_pair(5, "String18"));
  41.     MyMap.insert(std::make_pair(5, "String19"));
  42.     MyMap.insert(std::make_pair(5, "String20"));
  43.     MyMap.insert(std::make_pair(6, "String21"));
  44.     // the following statement demonstrates how to use the CConditionCombination 
  45.     CConditionCombination<int, std::string> Test(MyMap, 35);
  46.     Test.SetCmpPrecision(0); // you can also set the CmpPrecision 1 to try...
  47.     std::vector<std::multimap<int, std::string> > Result;
  48.     Test.Make(Result);
  49.     Display(Result);
  50.     std::cout<<"There are "<<Result.size()<<" groups"<<std::endl;
  51.     getchar();
  52.     // you can also set KEYTYPE float to try..., but don't forget to set CmpPrecision
  53.     return 0;
  54. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值