RNA主要是將vector<Cartridge2>包起來,並且可以操作「除了vector之外的相關操作」。而它最特別的操作,就是取值這件事。
為了將某特定點的特定資料「找出來」,在此是使用CartridgeFinder重建關鍵字,再將關鍵字放進for迴圈對整串走訪,做字串的比對,問題就在於,萬一找不到,要返回什麼值?在下面會有詳細的解說以及Sample code
另外,有一個防呆設計
sFind和fFind,是回傳條件搜尋的結果,只是這兩個函數的關鍵字都需要加上雙引號。有時忘記加雙引號,在此,將錯用的介面設計出來,在函數的實作上做assert(),可以將錯誤突顯出來並更正,加上條件編譯,不影響release的code大小。
RNA.h
#ifndef RNA_H
#define RNA_H
#include <vector>
#include <iterator>
#include "Cartridge2.h"
#include "CartridgeFinder.h"
#include "TxtFile.h"
#include "debugFile.h"
class RNA
{
std::vector<Cartridge2> m_CarChain2;
CString m_desktopPath;
//建解構子
public:
RNA();
virtual ~RNA();
//完全不像vector的操作
public:
void CutEqualCell(const RNA& );
void DeleteEmptyCell();
public:
std::vector<int>::size_type HaveSeveral(const CString& color = "", const CString& ptTotal = "",
const CString& mrIndex = "", const CString& fePara = "");
float fFind(const CString&, const CString&, const CString&, const CString&, const ValueKind&);
CString sFind(const CString&, const CString&, const CString&, const CString&, const ValueKind&);
#ifdef _DEBUG
public:
float fFind(const CString&, const int& , const CString&, const CString&, const ValueKind&);
CString sFind(const CString&, const int& , const CString&, const CString&, const ValueKind&);
float fFind(const CString&, const CString&, const int& , const CString&, const ValueKind&);
CString sFind(const CString&, const CString&, const int& , const CString&, const ValueKind&);
float fFind(const CString&, const int& , const int& , const CString&, const ValueKind&);
CString sFind(const CString&, const int& , const int& , const CString&, const ValueKind&);
private:
void paraError();
#endif
public:
Cartridge2& Find(const CString&, const CString&, const CString&, const CString&);
Cartridge2& Find(const CString& );
public:
void Empty();
const BOOL IsEmpty() const;
//像vector的函數
public:
const Cartridge2& At(const std::vector<Cartridge2>::size_type& _P) const;
std::vector<Cartridge2>::iterator Begin();
std::vector<Cartridge2>::const_iterator Begin() const;
std::vector<Cartridge2>::iterator End();
std::vector<Cartridge2>::const_iterator End() const;
const std::vector<Cartridge2>::size_type Size() const;
void AddCell(const RNA&);
void AddCell(const Cartridge2& _X);
//sorting
public:
void SortQuackMsr();
void SortOrigMsr();
private:
static bool areaPriority(const Cartridge2 &sp1, const Cartridge2 &sp2);
static bool origPriority(const Cartridge2 &sp1, const Cartridge2 &sp2);
//operator
public:
void operator+=(const RNA& _R);
void operator+=(const Cartridge2& _X);
//search
private:
CartridgeFinder finder;
//debug
private:
debugFile debugLogMaker;
};
#endif
RNA.cpp
x設計及其修正設計
在RNA設計了一個隱藏的元素x,在RNA的construct裡push_back進入m_CarChain2 (vector<Cartridge2>),若找不到這個元素,就返回這一個Cartridge x,它裡面的值都是垃圾值。為了對應x的設計,Begin()、Size()、Empty()都另外做了修正設計。RNA::RNA() { Cartridge2 x; m_CarChain2.push_back(x); } std::vector<Cartridge2>::iterator RNA::Begin() { return (m_CarChain2.size() <= 1) ? m_CarChain2.end() : m_CarChain2.begin() +1; } const std::vector<Cartridge2>::size_type RNA::Size () const { return m_CarChain2.size()-1; }; void RNA::Empty() { m_CarChain2.clear(); Cartridge2 x; m_CarChain2.push_back(x); }
簡化增加元素的介面
用一致的介面來表達一致的概念,即使C++的STL是使用不同的介面,也要用overload包成相同的介面。在此的概念:可以增加一個量測點位,也可以增加一個量測項目。
void RNA::AddCell(const RNA& _R)
{
m_CarChain2.insert(End(), _R.Begin(), _R.End());
}
void RNA::AddCell(const Cartridge2& _X)
{
m_CarChain2.push_back(_X);
}
剪掉相同的元素
這是一個STL沒有而需要的功能,量測點不重覆,再新增進來的相同點,必須是覆蓋原有的量測點。所以,在新增量過的量測點進來之前,要先去除掉原有而相同的量測點。在此有兩個版本,其實都一樣,一個是主要功能版(較少的那一段),另一個是主要功能+程式記錄功能,幫助debug用的。void RNA::CutEqualCell(const RNA& compData)
{
if (!compData.IsEmpty())//裡面這些不要修改,影響再次量測的資料擺放
{
//在這時m_CarChain2是舊, compData是新的
std::vector::const_iterator rnaitor = 0, compItor;
//remove & cut 在新的裡面,比對舊的,代表重覆,重覆量測去除掉
std::vector::iterator removeItor(End());
for (compItor = compData.Begin(); compItor != compData.End(); ++compItor)
//移動一個元素到最後,就刪掉
removeItor = std::remove(Begin(), removeItor, *compItor);//確認compData的資料是沒錯的
m_CarChain2.erase(removeItor, End());
}
}
加入一些debug的code,讓程式的運作有記錄,利用條件編譯的技巧讓複雜的debug code可以一直留著,不影響release的效能。
void RNA::CutEqualCell(const RNA& compData)
{
if (!compData.IsEmpty())//裡面這些不要修改,影響再次量測的資料擺放
{
CString str;
debugLogMaker.Clear();
//在這時m_CarChain2是舊, compData是新的
std::vector::const_iterator rnaitor = 0, compItor;
debugCode(
str.Format("Begin: %X, End: %X\n", Begin(), End());
debugLogMaker.Add(str);
debugLogMaker.Add("\nRNA原本的位址\n");
for (rnaitor = m_CarChain2.begin();
rnaitor != m_CarChain2.end(); ++rnaitor)
{
str.Format("%X, c(%d, %d, %d), P(%d, %d), status: %s\n",\
rnaitor,\
rnaitor->GetBkColor().R(), rnaitor->GetBkColor().G(), rnaitor->GetBkColor().B(),\
rnaitor->GetPointPosi().x, rnaitor->GetPointPosi().y,\
rnaitor->GetStrBkStatus());
debugLogMaker.Add(str);
}
debugLogMaker.Add("\ncompData的位址\n");
for (compItor = compData.Begin(); compItor != compData.End(); ++compItor)
{
str.Format("%X, c(%d, %d, %d), P(%d, %d), status: %s\n",\
compItor,\
compItor->GetBkColor().R(), compItor->GetBkColor().G(), compItor->GetBkColor().B(),\
compItor->GetPointPosi().x, compItor->GetPointPosi().y,\
compItor->GetStrBkStatus());
debugLogMaker.Add(str);
}
)
//remove & cut 在新的裡面,比對舊的,代表重覆,重覆量測去除掉
debugCode(
str.Format("\nremoveItor:\n");
debugLogMaker.Add("\nremoveItor:\n");
)
std::vector::iterator removeItor(End());
for (compItor = compData.Begin(); compItor != compData.End(); ++compItor)
{
//移動一個元素到最後,就刪掉
debugCode(
str.Format("B. %X\n", removeItor);
debugLogMaker.Add(str);
)
removeItor = std::remove(Begin(), removeItor, *compItor);//確認compData的資料是沒錯的
debugCode(
str.Format("A. %x\n", removeItor);
debugLogMaker.Add(str);
)
}
m_CarChain2.erase(removeItor, End());
debugCode(
debugLogMaker.Add("\nRNA後來的位址\n");
for (rnaitor = m_CarChain2.begin();
rnaitor != m_CarChain2.end(); ++rnaitor)
{
str.Format("%X, c(%d, %d, %d), P(%d, %d), status: %s\n",\
rnaitor,\
rnaitor->GetBkColor().R(), rnaitor->GetBkColor().G(), rnaitor->GetBkColor().B(),\
rnaitor->GetPointPosi().x, rnaitor->GetPointPosi().y,\
rnaitor->GetStrBkStatus());
debugLogMaker.Add(str);
}
)
}
CColorEyeIApp* pApp = dynamic_cast(AfxGetApp());
ASSERT_VALID(pApp);
DebugCode( m_desktopPath.Format("%s", pApp->GetDesktopPath()); )
debugLogMaker.Out2File(m_desktopPath+"//RNA_address.log");
}
去除空的元素
這是一個STL沒有而需要的功能,先辨別出什麼是空的,串成一串,再丟進剪掉相同的元素void RNA::DeleteEmptyCell()
{
RNA ready2Cut;
for (std::vector::iterator itor = Begin(); itor != End(); ++itor)
{
if (itor->GetBullet().IsEmpty() == TRUE)
ready2Cut.AddCell(*itor); //要剪掉的
}
CutEqualCell(x);
}
用精準Search、條件Search出想要的元素
三個功能- 有沒有存在: 回傳存在幾個
- 條件搜尋: 回傳搜尋到的元素,並且檢查是否唯一
- 精準搜尋: 回傳搜尋到的元素,並且檢查是否唯一
std::vector::size_type RNA::HaveSeveral(const CString& color, const CString& ptTotal, const CString& mrIndex, const CString& fePara)
{
CString clr(color);
CString ptTtl(ptTotal);
CString mrIdx(mrIndex);
CString fePr(fePara);
std::vector vSub;
if ( finder.ReconstrKeyWord(clr, ptTtl, mrIdx, fePr) )
{
for (std::vector::iterator itor = m_CarChain2.begin(); itor != m_CarChain2.end(); ++itor)
{
if ( (itor->GetDescrip().Find(clr) >= 0) && (itor->GetDescrip().Find(ptTtl) >= 0) &&
(itor->GetDescrip().Find(mrIdx) >= 0) && (itor->GetDescrip().Find(fePr) >= 0) )
vSub.push_back(itor - m_CarChain2.begin());
}
}
return vSub.size();
}
Cartridge2& RNA::Find(const CString& color, const CString& ptTotal, const CString& mrIndex, const CString& fePara)
{
/*
將關鍵字切成 1. x色, 2. x點, 3. 第x點, 4. 離邊參數 三個部份
然後重建成三個詞(三個函數)
再進行交集搜尋(試試可以可以使用遞迴)
*/
CString clr(color);
CString ptTtl(ptTotal);
CString mrIdx(mrIndex);
CString fePr(fePara);
CString sample;
std::vector vSub;
if (finder.Reconstr(clr, ptTtl, mrIdx, fePr))
{
sample.Format("%s%s%s%s", clr, ptTtl, mrIdx, fePr);
for ( std::vector::const_iterator itor = m_CarChain2.begin(); itor != m_CarChain2.end(); ++itor)
{
if ( itor->GetDescrip().Find(sample) >= 0 )
{
CString debugCharPtr = itor->GetDescrip();
vSub.push_back(itor - m_CarChain2.begin());
}
}
}
if (vSub.size() == 1)
return m_CarChain2.at(vSub.at(0));
else
return m_CarChain2.at(0);
}
Cartridge2& RNA::Find(const CString& sample)
{
/*
將關鍵字切成 1. x色, 2. x點, 3. 第x點, 4. 離邊參數 三個部份
然後重建成三個詞(三個函數)
再進行交集搜尋(試試可以可以使用遞迴)
*/
CString smple(sample);
std::vector vSub;
if (finder.Reconstr(smple))
{
for (std::vector::const_iterator itor = m_CarChain2.begin(); itor != m_CarChain2.end(); ++itor)
{
//if (sample == itor->GetDescrip())
if ( itor->GetDescrip().Find(smple) >= 0 )
vSub.push_back(itor - m_CarChain2.begin());
}
}
if (vSub.size() == 1)
return m_CarChain2.at(vSub.at(0));
else
return m_CarChain2.at(0);
}
沒有留言:
張貼留言