本文主要涉及boost中algorithm之string問題
基本的字符串函數類型有
替換
裁剪
大小寫替換
正則表達式
切割
判斷
和擦除操作等等
//! boost之2:字符串算法類
#include <string>
#include <vector>
#include <iostream>
#include <iterator>
#include <functional>
#include <boost/algorithm/string.hpp>
using namespace std;
using namespace boost;
int main()
{
//! 字符串
string str(" abc-*-ABC-*-aBc ");
//! 以-或者*切割字符串
vector<std::string> ret;
split(ret,str,is_any_of("-*"),token_compress_on);
for(unsigned int index=0;index<ret.size();index++)
{
cout<<index<<":"<<ret[index]<<endl;
};
//! 切換為小寫
to_lower(str);
cout<<"*"<<str<<"*"<<endl;
//! 去掉左邊的空格
trim_left(str);
cout<<"*"<<str<<"*"<<endl;
//! 去掉右邊的空格
trim_right(str);
cout<<"*"<<str<<"*"<<endl;
//! 替換
replace_all(str,"a","A");
cout<<str<<endl;
//! 擦除
cout<<erase_all_copy(str,"A")<<endl;
replace_nth(str,"c",2,"ccsdu2004");
cout<<str<<endl;
//! 擦除給定范圍
cout<<erase_range_copy(str,make_iterator_range(str.begin()+2,str.begin()+5))<<endl;
cout<<"is start with:A:"<<starts_with(str,string("A"))<<endl;
cout<<"is end with:C:"<<ends_with(str,string("C"))<<endl;
cout<<"is contain with:ccs:"<<contains(str,string("ccs"))<<endl;
cout<<endl;
system("PAUSE");
return 0;
}
發(fā)一系列關于boost庫的使用文章以備使用
//! boost庫引導1.minmax
#include <list>
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <boost/algorithm/minmax.hpp>
#include <boost/algorithm/minmax_element.hpp>
using namespace std;
inline void Print(int i)
{
std::cout<<i<<std::endl;
}
inline int Rand()
{
return rand()%10;
}
int main()
{
list<int> l;
typedef list<int>::const_iterator iterator;
//! 使用給定泛函子生成12個隨機數并推入鏈表
generate_n(front_inserter(l),12,Rand);
std::for_each(l.begin(),l.end(),Print);
std::cout<<"list size is:"<<l.size()<<std::endl;
//! 獲取給定序列的對大最小值,返回為std::pair<..,..>
pair<iterator,iterator> result = boost::minmax_element(l.begin(),l.end());
cout<<"the smallest element is:"<<*(result.first)<<endl;
cout<<"the largest element is:"<<*(result.second)<<endl;
//! 獲取第一個最小元素
iterator minitr = boost::first_min_element(l.begin(),l.end());
cout<<"first min element is:"<<*minitr<<endl;
system("PAUSE");
return 1;
}
//! 后論:似乎沒看到什么強大的功能
//!ccsdu2004
如下:
int Parse(int argc,char* argv[])
{
if(argc < 2)
{
cout<<"need para."<<endl;
system("PAUSE");
return -1;
}
bool is_input_file_para = false;
bool is_output_file_para = false;
for(int i = 1; i < argc;i++)
{
if(strcmp(argv[i],"-read") == 0)
{
is_input_file_para = true;
is_output_file_para = false;
}
else if(strcmp(argv[i],"-write") == 0)
{
is_input_file_para = false;
is_output_file_para = true;
}
else
{
if(is_input_file_para == true)
{
input_file_name = argv[i];
is_output_file_para = true;
}
else if(is_output_file_para == true)
{
output_file_name = argv[i];
is_input_file_para = true;
}
}
}
return 1;
}
該函數解析命令行獲取輸入文件和輸出文件名字
使用方法為:
srilm_lm -read gonewiththewind.count -write gonewiththewind.lm
其中srilm_lm為程序名
該函數可使用于win32和utunbu下
由于需要使用c++對字符串進行切割
故對相關的知識做一個總結
1.使用
std::stringstream
切割字符串
比如:
std::stringstream str(text);
std::string tok;
while(getline(str,tok,(char)32)){}
2.還是使用std::stringstream流析出
比如:
std::stringstream str(s);
string t1,t2,t3,t4;
str >>t1;
str >>t2;
str >>t3;
str >>t4;
3.使用strtok
比如:
char* token = strtok(str.c_str()," ");
4.使用boost的
tokenizer
比如:
boost::tokenizer<> ss(s,char_separator(' '));
for(boost::tokenizer<>::iterator beg=ss.begin(); beg!=ss.end(); ++beg){cout<<*beg<<endl;}
不過其默認的分隔為空格和標點符號
如果需要定制其模板參數
可以按照下面的書寫:
class char_separator
{
public:
char_separator(char c):sep(c){}
void reset(){}
template <typename InputIterator,typename Token>
bool operator()(InputIterator& next,InputIterator end,Token& tok)
{
tok = Token();
for(;next != end && *next == sep;++next);
if (next == end)
return false;
for(;next != end && *next != sep;++next)
{
tok += *next;
}
return true;
}
private:
char sep;
};
比如:
boost::tokenizer<char_separator> mytok(str,char_separator('@'));
for(boost::tokenizer<char_separator>::iterator beg=mytok.begin(); beg!=mytok.end(); ++beg)
{
if(index == 0)
text1 = *beg;
else if(index == 1)
text2 = *beg;
else if(index == 2)
text3 = *beg;
else if(index == 3)
text4 = *beg;
index++;
}
5.還是boost.
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <iostream>
#include <iterator>
#include <functional>
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/find_iterator.hpp>
using namespace std;
using namespace boost;
int main(int argc, char *argv[])
{
vector<string> strlist;
string str("12 34 56 678 ccsdu2004");
split(strlist,str,is_any_of(" "),token_compress_on);
for(unsigned int index=0;index<strlist.size();index++)
{
cout<<index <<":"<<strlist[index]<<endl;
};
system("PAUSE");
return EXIT_SUCCESS;
}
6.其他不知道的方法若干
...
Srilm的全稱是Stanford Research Institute Language Modeling Toolkit
他被用來構建和應用統(tǒng)計語言模型,主要用于語音識別,統(tǒng)計標注和切分,以及機器翻譯等工作
由于需要我要在win32下編譯她
可是在網上找到很多都是基于cygwin的交叉式編譯
使用起來總是有點問題
不過還好找到了一個使用srilm的vc解決方案
在這里:
http://www.inference.phy.cam.ac.uk/kv227/srilm/
然后需要做的就是下載srilm解壓放在srilm_vc2008 or srilm_2005文件夾下編譯即可
插件系統(tǒng)是游戲引擎中一個比較大的子系統(tǒng)
這個系統(tǒng)的目的就是動態(tài)增加引擎的功能而不必修改引擎接口
之前雖然做過插件這塊‘
但是感覺設計的不好
這次總算弄了一個比較完備的插件系統(tǒng)
相關對象和結構
1.插件 Plugin
///////////////////////////////////////////////////////////
/// 定義引擎插件數據結構
///////////////////////////////////////////////////////////
class Plugin
{
public:
Plugin()
{
Reset();
}
///////////////////////////////////////////////////////
/// 插件重啟
///////////////////////////////////////////////////////
void Reset();
///////////////////////////////////////////////////////
/// 插件名字
///////////////////////////////////////////////////////
engine_string name;
///////////////////////////////////////////////////////
/// 插件作者
///////////////////////////////////////////////////////
engine_string maker;
///////////////////////////////////////////////////////
///插件描述
///////////////////////////////////////////////////////
engine_string description;
///////////////////////////////////////////////////////
/// 插件版本
///////////////////////////////////////////////////////
ushort vermain;
ushort versub;
ushort verpitch;
///////////////////////////////////////////////////////
/// 插件類型
///////////////////////////////////////////////////////
ushort type;
///////////////////////////////////////////////////////
/// 插件合法性標記
///////////////////////////////////////////////////////
ushort valid;
};
插件數據結構只包含了插件的一些基本信息 比如名字,描述,作者,功能類型等
2.PluginLoader
////////////////////////////////////////////////////////
/// 定義插件載入類
////////////////////////////////////////////////////////
class PluginLoader
{
public:
/////////////////////////////////////////////////////
/// 構造,析構插件載入
/////////////////////////////////////////////////////
PluginLoader();
~PluginLoader();
public:
/////////////////////////////////////////////////////
/// 載入插件和卸載
/////////////////////////////////////////////////////
bool Load(const engine_string &plugin);
void Free();
/////////////////////////////////////////////////////
/// 獲取插件指定符號地址
/////////////////////////////////////////////////////
void* GetAddress(const engine_string &name);
/////////////////////////////////////////////////////
/// 檢測插件是否合法
/////////////////////////////////////////////////////
bool IsValid()const{return handle != NULL;}
/////////////////////////////////////////////////////
/// 獲取插件句柄
/////////////////////////////////////////////////////
void* GetHandle(){return handle;}
void* GetHandle()const{return handle;}
/////////////////////////////////////////////////////
/// 獲取插件名
/////////////////////////////////////////////////////
engine_string GetPluginName()const{return pluginame;}
private:
void* handle;
engine_string pluginame;
};
PluginLoader主要是載入插件文件并獲取給定符號的函數指針
這個并沒沒有暴漏出來供用戶調用
3.PluginFactory
///////////////////////////////////////////////////////////
/// 定義引擎插件工廠基類
///////////////////////////////////////////////////////////
class GAPI PluginFactory : public Object
{
public:
///////////////////////////////////////////////////////
/// 構造和析構引擎插件工廠基類
///////////////////////////////////////////////////////
PluginFactory();
virtual ~PluginFactory();
public:
///////////////////////////////////////////////////////
/// 注冊,反注冊插件
///////////////////////////////////////////////////////
virtual bool ENGINE_CALL RegisterFactory(const engine_string& plugin) = 0;
virtual void ENGINE_CALL UnregisterFacory() = 0;
public:
///////////////////////////////////////////////////////
/// 獲取對應插件類型標識
///////////////////////////////////////////////////////
virtual ushort GetPluginType()const = 0;
private:
DECLARE_OBJECT(PluginFactory)
};
插件工廠是一切需要從插件中獲取功能的對象工廠
她主要提供了插件的注冊和反注冊以及獲取插件工廠所對應的插件類型
4.PluginManager 插件管理器
///////////////////////////////////////////////////////////
/// 定義引擎插件管理器
///////////////////////////////////////////////////////////
class GAPI PluginManager
{
public:
///////////////////////////////////////////////////////
/// 獲取,設置插件目錄
///////////////////////////////////////////////////////
engine_string GetPluginFolder()const;
void SetPluginFolder(const engine_string& folder);
public:
///////////////////////////////////////////////////////
/// 插件裝載和卸載
///////////////////////////////////////////////////////
void InstallPlugin();
void UnstallPlugin();
public:
///////////////////////////////////////////////////////
/// 注冊,反注冊插件工廠
///////////////////////////////////////////////////////
bool RegisterPluginFactory(PluginFactory* factory);
bool UnregisterPluginFactory(PluginFactory* factory);
public:
///////////////////////////////////////////////////////
/// 獲取插件個數
///////////////////////////////////////////////////////
ushort ENGINE_CALL GetPluginNumber()const;
///////////////////////////////////////////////////////
/// 獲取給定索引插件信息
///////////////////////////////////////////////////////
Plugin ENGINE_CALL GetPluginByType(ushort index)const;
///////////////////////////////////////////////////////
/// 獲取給定索引的插件名
///////////////////////////////////////////////////////
engine_string ENGINE_CALL GetPluginNameByType(ushort index)const;
///////////////////////////////////////////////////////
/// 獲取給定插件類型的插件載入類
///////////////////////////////////////////////////////
private:
PluginManagerImpl *impl;
DEFINE_SINGLETON(PluginManager);
};
}
//! 定義插件管理器單件
#define GLOBAL_PLUGINMANAGER_PTR (core::PluginManager::GetInstance())
插件管理器是插件系統(tǒng)的核心,充當了插件管理者的角色
要使用插件線需要設置插件目錄
然后裝載插件
然后注冊特定的插件工廠
然后就可以通過插件工廠獲取插件對象指針咯
在這里插件管理器是作為一個單間使用的
具體的宏 DEFINE_SINGLETON(PluginManager);
展開之后為:
#define DEFINE_SINGLETON(SingletonObject)\
private:\
static std::auto_ptr<SingletonObject> instance;\
protected:\
SingletonObject();\
public:\
~SingletonObject();\
static SingletonObject* GetInstance(){\
if(!instance.get())\
{\
instance = std::auto_ptr<SingletonObject>(new SingletonObject());\
}\
return instance.get();\
}
#define IMPLEMENT_SINGLETON(SingletonObject)\
std::auto_ptr<SingletonObject> SingletonObject::instance(NULL);
下面是具體的一個插件對象---攝像頭捕獲類
如下:通過調用CaptureImage就可以把攝像頭所見程序保存為image了
///////////////////////////////////////////////////////////
/// 定義攝像頭捕獲類(以插件形式提供之)
///////////////////////////////////////////////////////////
class GAPI CapturePicture : public Object
{
public:
///////////////////////////////////////////////////////
/// 構造和析構
///////////////////////////////////////////////////////
CapturePicture();
virtual ~CapturePicture();
public:
///////////////////////////////////////////////////////
/// 獲取攝像頭圖形數據
///////////////////////////////////////////////////////
virtual bool CaptureImage(RefPtr<Image> &image);
private:
DECLARE_OBJECT(CapturePicture)
};
通過調用CaptureImage就可以把攝像頭所見程序保存為image了
下面這個是對于的工廠:
///////////////////////////////////////////////////////////
/// 定義攝像頭捕獲工廠類
///////////////////////////////////////////////////////////
class GAPI CapturePictureFactory : public PluginFactory
{
public:
///////////////////////////////////////////////////////
/// 構造和析構
///////////////////////////////////////////////////////
CapturePictureFactory();
virtual ~CapturePictureFactory();
public:
///////////////////////////////////////////////////////
/// 獲取攝像頭捕獲指針
///////////////////////////////////////////////////////
CapturePicture* Create();
///////////////////////////////////////////////////////
/// 注冊插件
///////////////////////////////////////////////////////
bool ENGINE_CALL RegisterFactory(const engine_string& plugin);
void ENGINE_CALL UnregisterFacory();
///////////////////////////////////////////////////////
/// 獲取對應插件類型標識
///////////////////////////////////////////////////////
ushort GetPluginType()const;
private:
PluginLoader* loader;
DECLARE_OBJECT(CapturePictureFactory)
};
這個只是多了一個函數Createer而已
然后再說具體的插件部分
插件3函數:
extern "C" void GAPI Plugin_Info(Plugin &plugin);
extern "C" Object* GAPI Plugin_Install();
extern "C" void GAPI Plugin_Unstall(void*);
具體為通過Plugin_Info
通過Plugin_Install獲取插件實際對象指針
通過Plugin_Unstall卸載插件
最后一個部分是插件的使用小例子:
#include <cstdlib>
#include <iostream>
#include <GEngine/Header.hpp>
using namespace std;
int main(int argc, char *argv[])
{
GLOBAL_PLUGINMANAGER_PTR->SetPluginFolder("plugin");
GLOBAL_PLUGINMANAGER_PTR->InstallPlugin();
std::cout<<"插件個數:"<<GLOBAL_PLUGINMANAGER_PTR->GetPluginNumber()<<std::endl;
core::CapturePictureFactory factory;
std::cout<<"注冊視頻捕獲插件工廠:"<<GLOBAL_PLUGINMANAGER_PTR->RegisterPluginFactory(&factory)<<std::endl;
core::CapturePicture* capturepicture = factory.Create();
std::cout<<"插件工廠產品標識:"<<factory.GetPluginType()<<std::endl;
core::RefPtr<core::Device> device = core::InitDevice("插件測試");
if(!capturepicture)
{
std::cout<<"生成攝像頭捕獲指針失敗了"<<std::endl;
system("PAUSE");
return -1;
}
core::RefPtr<core::ResourceManager> resmgr = device->GetResourceManager();
core::RefPtr<core::ImageManager> imagemanager = resmgr->GetImageManager();
core::RefPtr<core::Image> image = imagemanager->CreateObject("capturepicture");
capturepicture->CaptureImage(image);
std::cout<<"save image is:"<<image->Save("capture.bmp")<<std::endl;
BEGIN_LOOP(device)
glClearColor(0.1,0.3,0.2,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
END_LOOP(device)
GLOBAL_PLUGINMANAGER_PTR->UnregisterPluginFactory(&factory);
GLOBAL_PLUGINMANAGER_PTR->UnstallPlugin();
//system("PAUSE");
return EXIT_SUCCESS;
}
題后話:
當前引擎支持xp,vista,win7環(huán)境
在編譯器支持vc7.1,vc8,vc9,devc++,codeblock
也許在不久的將來我會弄一個linux版本的
一直以來使用FreeImage保存圖像總是采用下面的辦法:
FIBITMAP* bitmap =FreeImage_Allocate(width,height,24);
const unsigned char* source = data;
for(int y=0; y < height; y++ )
{
unsigned char* scanline = (unsigned char*)FreeImage_GetScanLine(bitmap, height - y - 1 );
memcpy(scanline,data,sizeof(source[0]) * width);
data += width;
}
FreeImage_Save(FIF_BMP,bitmap,file,0)
不過今天看到了函數:
FreeImage_ConvertFromRawBits
使用它可以更加快速的保存圖形
如下:
FIBITMAP* bitmap = FreeImage_ConvertFromRawBits(data,width,height,pitch,24,FI_RGBA_BLUE_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_RED_MASK,FALSE);
然后調用FreeImageSave即可
另外關于獲取FreeImage圖形到數組
也有2個辦法
一個是逐行復制
一個是使用memcpy(data,FreeImage.GetDibBits())
當然也可以逐像素復制咯
大律法求取圖形閾值
放在這里
int GetOtsuValue(unsigned char* data,int width,int height)
{
int table[256];
memset(table,0,sizeof(int)*256);
for(int i = 0; i < width*height;i++)
{
table[data[i]] ++;
}
int sum = 0;
for(int i = 0 ;i < 256;i++)
{
sum += table[i];
if(sum >= width*height*0.5)
return i;
}
return 255;
}
1.C風格的鏈接方式
比如:
#define GAPI G_DLL_API
#define G_FUNC(ret) extern "C" GAPI ret
編譯函數:
G_FUNC(Vector3) GetRandVec3();
對于msvc系列編譯器是不允許的
對于mingw系列是被允許的咯
2.對模板支持的差別
對沒有實際調用的模板類成員函數存在的問題處理方式的差異
msvc可以給出編譯錯誤
mingw不能
舉例來說:
template <class T>
struct Vec2
{
Vec2();
Vec2(T x,T y);
Vec2<T> operator+=(const Vec2& v2)
{
return Vec(x+v2.x,y+v2.y_);
}
T x_,y_;
};
實例化為
Vec2<int> v2;
3.對靜態(tài)浮點類型成員變量處理的差異
msvc不允許靜態(tài)浮點類型的成員變量
比如
struct Math
{
static const float PI = 3.14.15925f;
};
mingw是允許的
先放這里改天寫吧!