// PrefixSpan.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include<iostream>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<string>
using namespace std;
//data format
typedef vector<vector<vector<string>>> strTVect;
typedef vector<vector<string>> strDVect;
typedef vector<string> strVect;
//item and occur times
typedef map<string,int> strIntMap;
//items' name
typedef set<string> strSet;
//project data
typedef map<string,strTVect> vectMap;
void showData(strTVect datas)
{
strTVect::const_iterator strTIter;
strDVect::const_iterator strDIter;
strVect::const_iterator strIter;
for(strTIter = datas.begin(); strTIter != datas.end(); strTIter++)
{
for(strDIter = strTIter->begin(); strDIter != strTIter->end(); strDIter++)
{
string temp = "";
for(strIter = strDIter->begin(); strIter != strDIter->end(); strIter++)
{
temp += *strIter;
}
cout.width(5);
cout << setiosflags(ios::left) << temp;
}
cout << endl;
}
}
//get length-1 items
strIntMap getItems(strTVect datas,strSet items,int threshold)
{
strTVect::const_iterator strTIter;
strDVect::const_iterator strDIter;
strVect::const_iterator strIter;
//item and occur times
strIntMap itemsMap;
//get all possible items;
for(strTIter = datas.begin(); strTIter != datas.end(); strTIter++)
{
//element
strSet temp = items;
for(strDIter = strTIter->begin(); strDIter != strTIter->end(); strDIter++)
{
//item
for(strIter = strDIter->begin(); strIter != strDIter->end(); strIter++)
{
if(temp.find(*strIter) != temp.end())
{
if(itemsMap.find(*strIter) != itemsMap.end())
{
itemsMap.find(*strIter)->second++;
}
else
{
itemsMap.insert(make_pair(*strIter,1));
}
temp.erase(*strIter);
}
}
}
}
//filt by threshold
strIntMap::iterator mapIter;
for(mapIter = itemsMap.begin(); mapIter != itemsMap.end();)
{
if(mapIter->second < threshold)
{
//put the return iterator to mapIter
mapIter = itemsMap.erase(mapIter);
}
else
{
mapIter++;
}
}
////show
//for(mapIter = itemsMap.begin(); mapIter != itemsMap.end(); mapIter++)
//{
// cout << mapIter->first << " " << mapIter->second << endl;
//}
return itemsMap;
}
void filtDataByItems(strTVect &datas, strIntMap itemsMap)
{
strTVect::iterator strTIter;
strDVect::iterator strDIter;
strVect::iterator strIter;
for(strTIter = datas.begin(); strTIter != datas.end();)
{
//element
for(strDIter = strTIter->begin(); strDIter != strTIter->end();)
{
//item
for(strIter = strDIter->begin(); strIter != strDIter->end();)
{
//remove from item
if(itemsMap.find(*strIter) == itemsMap.end())
{
strIter = strDIter->erase(strIter);
}
else
{
strIter++;
}
}
//pay attention to erase some value
//if(strDIter->empty())
if(strDIter->size() == 0)
{
strDIter = strTIter->erase(strDIter);
}
else
{
strDIter++;
}
}
if(strTIter->empty())
{
strTIter = datas.erase(strTIter);
}
else
{
strTIter++;
}
}
}
//divide search place by first prefix or get the project like <30 x>
vectMap simpleProjectData(strTVect datas,int threshold)
{
strTVect::const_iterator strTIter;
strDVect::const_iterator strDIter;
strVect::const_iterator strIter;
strTVect pTVect;
strDVect pDVect;
strVect pVect;
vectMap pVectMap;
strSet items;
for(strTIter = datas.begin(); strTIter != datas.end(); strTIter++)
{
items.clear();
//element
for(strDIter = strTIter->begin(); strDIter != strTIter->end(); strDIter++)
{
//item
for(strIter = strDIter->begin(); strIter != strDIter->end(); strIter++)
{
//this element is the same as the last element of prefix
//it doesn't work at the first call
//it works when call by projectData function
if(*strIter == "_")
{
break;
}
//if find a strIter without sequence then add to pVectMap
if(items.find(*strIter) == items.end())
{
//cout << *strIter << endl;
strVect::const_iterator tempIter;
strDVect::const_iterator tempDIter;
pDVect.clear();
//traverse the last part of element
if((strIter+1) != strDIter->end())
{
pVect.clear();
pVect.push_back("_");
for(tempIter = strIter+1; tempIter != strDIter->end(); tempIter++)
{
pVect.push_back(*tempIter);
}
pDVect.push_back(pVect);
}
//traverse the last part of sequence
for(tempDIter = strDIter+1; tempDIter != strTIter->end(); tempDIter++)
{
pDVect.push_back(*tempDIter);
}
//add to project data
if(pVectMap.find(*strIter) == pVectMap.end())
{
pTVect.clear();
pTVect.push_back(pDVect);
pVectMap.insert(make_pair(*strIter,pTVect));
}
else
{
pVectMap.find(*strIter)->second.push_back(pDVect);
}
items.insert(*strIter);
}
}
}
}
//filt project data by threshold
vectMap::iterator vMIter;
for(vMIter = pVectMap.begin(); vMIter != pVectMap.end();)
{
if(vMIter->second.size() < threshold)
{
vMIter =pVectMap.erase(vMIter);
}
else
{
vMIter++;
}
}
return pVectMap;
}
//find prefix like <(30 x)>,<(_ x)>
vectMap normalProjectData(strTVect datas,strDVect prefix, int threshold)
{
vectMap pVectMap;
strTVect::const_iterator strTIter;
strDVect::const_iterator strDIter;
//strIter2:the last item of last element of prefix
strVect::const_iterator strIter,strIter2;
strTVect pTVect;
strDVect pDVect;
strVect pVect,preVect;
strSet items;
//get the last element of prefix
preVect = prefix.at(prefix.size()-1);
for(strTIter = datas.begin(); strTIter != datas.end(); strTIter++)
{
items.clear();
//element
for(strDIter = strTIter->begin(); strDIter != strTIter->end(); strDIter++)
{
//item
for(strIter = strDIter->begin(); strIter != strDIter->end(); strIter++)
{
if(*strIter == "_")
{
strIter2 = preVect.end();
strIter++;
}
else
{
//find the same of the last element of prefix
for(strIter2 = preVect.begin(); strIter2 != preVect.end() && strIter != strDIter->end();)
{
//*strIter equal *strIter2
if(*strIter == *strIter2)
{
strIter++;
strIter2++;
}
else
{
break;
}
}
}
string temp;
if(strIter2 == preVect.end() && strIter != strDIter->end())
{
//if find a strIter without sequence then add to pVectMap
if(items.find(*strIter) == items.end())
{
temp = *strIter;
pDVect.clear();
if((strIter+1) != strDIter->end())
{
pVect.clear();