前期研究
-
abc{\W2;abc\W4;abc}
-
{\W4;abc\W2;abc}abc
-
abc{\W4;abc}abc\Pabc\Pa{\W4;bc\W2;ab\P\W4;abc\P}abcdeg{ab}a{\W4;bc\Pd}
- abc\P{\W4;abc\P}abc
算法思路
/*
示例:
1.abc{\W2;abc\W4;abc}
2.{\W4;abc\W2;abc}abc
3.abc{\W4;abc}abc\Pabc\Pa{\W4;bc\W2;ab\P\W4;abc\P}abcdeg\{ab\}a{\W4;bc\Pd}
4.abc\P{\W4;abc\P}abc
算法:
结果数据结构如下:
行字符串1
宽高比1-字符串2
宽高比2-字符串2
...
行字符串2
宽高比1-字符串2
宽高比2-字符串2
...
...
算法思路描述:
当前宽高比ws = 1.0
遍历字符串
IF 出现转义字符:'\',则进入转义逻辑
'W': 新的宽高比,设置给ws
'P': 换行
其他(如'{', '}'等):加入当前字符串
ELSE IF出现’{‘
宽高比ws将要变化
ELSE IF出现’}’
宽高比ws恢复1.0
ELSE
字符加入到当前字符串
*/
示例代码
#include <iostream>
#include <memory>
#include <string>
#include <list>
#include <vector>
/*
示例:
1.abc{\W2;abc\W4;abc}
2.{\W4;abc\W2;abc}abc
3.abc{\W4;abc}abc\Pabc\Pa{\W4;bc\W2;ab\P\W4;abc\P}abcdeg\{ab\}a{\W4;bc\Pd}
4.abc\P{\W4;abc\P}abc
算法:
结果数据结构如下:
行字符串1
宽高比1-字符串2
宽高比2-字符串2
...
行字符串2
宽高比1-字符串2
宽高比2-字符串2
...
...
算法思路描述:
当前宽高比ws = 1.0
遍历字符串
IF 出现转义字符:'\',则进入转义逻辑
'W': 新的宽高比,设置给ws
'P': 换行
其他(如'{', '}'等):加入当前字符串
ELSE IF出现’{‘
宽高比ws将要变化
ELSE IF出现’}’
宽高比ws恢复1.0
ELSE
字符加入到当前字符串
*/
typedef std::list<std::pair<double, std::shared_ptr<std::string>>> OneLineText; //一行文本
typedef std::list<std::shared_ptr<OneLineText>> MutiLineText; //多行文本
//倾印多行文本
void DumpMutiLineText(const MutiLineText& mMutiLineText)
{
for (auto it = mMutiLineText.begin(); it != mMutiLineText.end(); ++it)
{
auto pOneLineText = *it;
if (!pOneLineText) continue;
std::cout << "一行文本:" << std::endl;
for (auto itSub = pOneLineText->begin(); itSub != pOneLineText->end(); ++itSub)
{
auto pString = itSub->second;
if (!pString) continue;
std::cout << "\t" << itSub->first << " " << pString->c_str() << std::endl;
}
std::cout << std::endl;
}
}
//新行文本
std::shared_ptr<std::string> NewLineText(MutiLineText& mMutiLineText, double dCurWidthScale )
{
auto pNewString = std::make_shared<std::string>();//当前字符串
auto pNewLineText = std::make_shared<OneLineText>();
pNewLineText->push_back(std::pair<double, std::shared_ptr<std::string>>(dCurWidthScale, pNewString));
mMutiLineText.push_back(pNewLineText);
return pNewString;
}
//当前行中宽高比变化
std::shared_ptr<std::string> NewWidthScaleAtCurLine(MutiLineText& mMutiLineText, double dCurWidthScale)
{
if (mMutiLineText.size() == 0)
{
return nullptr; //逻辑错误
}
//当前行中宽度
std::shared_ptr<OneLineText> pCurLineText = mMutiLineText.back();
if (!pCurLineText)
{
return nullptr; //逻辑错误
}
auto pNewString = std::make_shared<std::string>();//当前字符串
pCurLineText->push_back(std::pair<double, std::shared_ptr<std::string>>(dCurWidthScale, pNewString));
return pNewString;
}
//解析MText
void ParseMutiText(const std::string& strMText, MutiLineText& mRtMutiLineText)
{
int nSize = int(strMText.size());
int i = 0;
double dCurWidthScale = 1.0; //当前宽高比
std::shared_ptr<std::string> pCurString = NewLineText(mRtMutiLineText, 1.0);
while (i < nSize && pCurString )
{
char c = strMText.at(i++);
switch (c)
{
case '\\'://出现转义字符,进入转义逻辑
{
if (i < nSize)
{
char c1 = strMText.at(i++);
switch (c1)
{
case 'W': //新的宽高比
{
std::string strWidth;
while (i < nSize)
{
char c2 = strMText.at(i++);
if (c2 == ';') break;
strWidth.push_back(c2);
}
dCurWidthScale = std::stod(strWidth);
pCurString = NewWidthScaleAtCurLine(mRtMutiLineText, dCurWidthScale);
break;
}
case 'P': //换行
{
pCurString = NewLineText(mRtMutiLineText, dCurWidthScale);
break;
}
default://其他(如'{', '}'等):加入当前字符串
{
if (pCurString) pCurString->push_back(c1);
break;
}
}
}
break;
}
case '{'://宽高比ws将要变化
{
break;
}
case '}'://宽高比ws恢复1.0
{
dCurWidthScale = 1.0;
pCurString = NewWidthScaleAtCurLine(mRtMutiLineText, dCurWidthScale);
break;
}
default://字符加入到当前字符串
{
if (pCurString) pCurString->push_back(c);
}
}
}
}
int main()
{
/*
1.abc{\W2;abc\W4;abc}
2.{\W4;abc\W2;abc}abc
3.abc{\W4;abc}abc\Pabc\Pa{\W4;bc\W2;ab\P\W4;abc\P}abcdeg\{ab\}a{\W4;bc\Pd}
4.abc\P{\W4;abc\P}abc
*/
std::vector<std::string> mMTextArray;
mMTextArray.push_back("abc{\\W2;abc\\W4;abc}");
mMTextArray.push_back("{\\W4;abc\\W2;abc}abc");
mMTextArray.push_back("abc{\\W4;abc}abc\\Pabc\\Pa{\\W4;bc\\W2;ab\\P\\W4;abc\\P}abcdeg\\{ab\\}a{\\W4;bc\\Pd}");
mMTextArray.push_back("abc\\P{\\W4;abc\\P}abc");
for (auto it = mMTextArray.begin(); it != mMTextArray.end(); ++it)
{
MutiLineText mMutiLineText;
ParseMutiText(*it, mMutiLineText);
DumpMutiLineText(mMutiLineText);
std::cout << "--------------------------------------------" << std::endl;
}
return 0;
}