问题描述
我正在用c ++创建类似于figlet的代码,并且当前正在通过在左侧字符处插入null并找到min space并删除minspace并使该字符null来进行拟合,(为了理解,将null用作'0'
)
" __0 "
"| _|0 "
"| |0 _____ "
"| |0 |_____|"
"| |0 $ "
"|__|0 "
(如果有任何空格行,我会在开始时插入null)现在这里的最小空格为3,因此我删除了3个空格和null,并且此代码通过继承fitting类而完美完美,并且我将通过右侧的char像
那样插入null" 0"
" 0"
" _0____ "
"|0_____|"
" $0 "
" 0"
它将给出类似的结果
" __ 0"
"| _| 0"
"| | _0____ "
"| ||0_____|"
"| | $0 "
"|__| 0"
现在我将存储null的pos并将其删除,在下一个循环中,检查null之前的两个字符,如果任何一个是HardBlank,则返回函数,否则我在下一个循环中将其涂抹,但是上面不是smush(not正常工作)(由于HardBlank),所以我想知道figlet实际上是如何伪装的,我从here下载了figlet代码,但我不理解该代码。
- 还有比这更好的算法,或者figlet如何实际拟合和涂抹?
欢迎所有建议, 预先感谢。
解决方法
我很久以前就问过这个问题,但我现在为未来的读者回答这个问题我前段时间写了比这更好的算法,执行以下操作,
字距调整或拟合:
这件事的主要部分是修剪,所以让我们创建一个函数,它接受两个输入,即 figs 是左侧 FIGchar 和 figc 是右侧 FIGchar。首先要做的是找到需要从 figs 右侧和 figc 左侧删除的空间数量,我们可以通过计算 figs 右侧和 figc 左侧的总空间来轻松找到这一点。最后取最小值,即此处必须删除的空间计数是该实现,
/**
* @brief trims in a deep
*
* @param figs fig string
* @param figc fig character
*/
void trim_deep(Figs_type &figs,Figc_type &figc) const
{
std::vector<size_type> elem;
for (size_type i = 0; i < figs.size(); ++i)
{
int lcount = 0,rcount = 0;
for (auto itr = figs[i].rbegin(); itr != figs[i].rend(); ++itr)
{
if (*itr == ' ')
++lcount;
else
break;
}
for (auto itr = figc[i].begin(); itr != figc[i].end(); ++itr)
{
if (*itr == ' ')
++rcount;
else
break;
}
elem.push_back(lcount + rcount);
}
size_type space = *std::min_element(elem.begin(),elem.end());
for (size_type i = 0; i < figs.size(); ++i)
{
size_type siz = space;
while (siz > 0 && figs[i].back() == ' ')
{
figs[i].pop_back();
--siz;
}
figc[i].erase(0,siz);
}
}
粉碎:
通过使用上面的函数可以很容易地完成这个 smushing,只需 smush figs 的最右侧字符和 figc 的左侧字符,如果它是 smushble 这里是实现,
/**
* @brief smush rules
* @param lc left character
* @param rc right character
* @return smushed character
*/
char_type smush_rules(char_type lc,char_type rc) const
{
//()
if (lc == ' ')
{
return rc;
}
if (rc == ' ')
{
return lc;
}
//(Equal character smush)
if (lc == rc)
{
return rc;
}
//(Underscores smush)
if (lc == '_' && this->cvt("|/\\[]{}()<>").find(rc) != string_type::npos)
{
return rc;
}
if (rc == '_' && this->cvt("|/\\[]{}()<>").find(lc) != string_type::npos)
{
return lc;
}
//(Hierarchy Smushing)
auto find_class = [](char_type ch) -> size_type
{
if (ch == '|')
{
return 1;
}
if (ch == '/' || ch == '\\')
{
return 3;
}
if (ch == '[' || ch == ']')
{
return 4;
}
if (ch == '{' || ch == '}')
{
return 5;
}
if (ch == '(' || ch == ')')
{
return 6;
}
return 0;
};
size_type c_lc = find_class(lc);
size_type c_rc = find_class(rc);
if (c_lc > c_rc)
{
return lc;
}
if (c_rc > c_lc)
{
return rc;
}
//(Opposite smush)
if (lc == '[' && rc == ']')
{
return '|';
}
if (lc == ']' && rc == '[')
{
return '|';
}
if (lc == '{' && rc == '}')
{
return '|';
}
if (lc == '}' && rc == '{')
{
return '|';
}
if (lc == '(' && rc == ')')
{
return '|';
}
if (lc == ')' && rc == '(')
{
return '|';
}
//(Big X smush)
if (lc == '/' && rc == '\\')
{
return '|';
}
if (lc == '\\' && rc == '/')
{
return 'Y';
}
if (lc == '>' && rc == '<')
{
return 'X';
}
//(universel smush)
return lc;
}
/**
* @brief smush algoriths on kerned Fig string and character
*
* @param figs
* @param figc
*/
void smush(Figs_type &figs,Figc_type figc,char_type hb) const
{
bool smushble = true;
for (size_type i = 0; i < figs.size(); ++i)
{
if (figs[i].size() == 0 || figc[i].size() == 0)
{
smushble = false;
}
else if ((figs[i].back() == hb) && !(figc[i].front() == hb))
{
smushble = false;
}
}
if (smushble)
{
for (size_type i = 0; i < figs.size(); ++i)
{
char_type val = smush_rules(figs[i].back(),figc[i].front());
figs[i].pop_back();
figc[i].erase(0,1);
figs[i] += string_type(1,val) + figc[i];
}
}
else
{
for (size_type i = 0; i < figs.size(); ++i)
{
figs[i] += figc[i];
}
}
}
这段代码是直接从这个file复制过来的,所以这里的类型可能会混淆,概述Figs_type
和Figc_type
就像字符串向量,其他类型反映在他们的名字中并且可以在 here 中找到该存储库。