class//RNA

裝載著每一個點特有參數的Cartridge2,將它串成一串vector,包成RNA(因為要由DNA轉錄出來),一些特定的點集成一串(9個點集成一串),就成為一個量測項目(白色9點),它可以由vector::iterator的操作,來切換量測點位,並且排序成特別的順序。
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出想要的元素

三個功能
  1. 有沒有存在: 回傳存在幾個
  2. 條件搜尋: 回傳搜尋到的元素,並且檢查是否唯一
  3. 精準搜尋: 回傳搜尋到的元素,並且檢查是否唯一
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);
}

沒有留言:

張貼留言

文章分類維度