如何为字符串类比较分配'-'等于'',这可能吗?
Posted
技术标签:
【中文标题】如何为字符串类比较分配\'-\'等于\'\',这可能吗?【英文标题】:How to assign '-' is equal to ' ' for string class compare, is this possible?如何为字符串类比较分配'-'等于'',这可能吗? 【发布时间】:2012-01-04 16:35:06 【问题描述】:我正在使用#string 中的string.compare 函数比较两个字符串str1 和str2。有没有办法强制班级认为'-'
等同于' '
。查看 char_traits 的成员函数,我认为 .assign 可以让我完成此任务,但它的行为就像我在说 str1='-';
或 str1=' ';
。我不想重写我自己的字符串处理类。
【问题讨论】:
我认为它通过比较字符值来进行比较;这意味着你必须让它认为45 == 32
。能否不复制字符串并将所有出现的'-'
替换为' '
,然后进行比较?
@Chad:这是一个空格,所以32
。
@LightnessRacesinOrbit 啊!不知道那里有一个空间!
@Chad:嗯,没有''
这样的东西:P
【参考方案1】:
在比较两个字符串之前复制所有出现的“-”并将其替换为“”怎么样?
【讨论】:
【参考方案2】:库中没有针对此类特定用例的任何内容,但自己很容易做到:
复制两个字符串。在每个中,将所有'-'
替换为' '
。然后对这些字符串进行比较;
或者,创建您的 自己的 函数,该函数遍历每个字符并与您描述的其他语义进行字典比较。这样做的好处是不需要字符串副本,但会编写更多代码并且可能更容易出错。
【讨论】:
我相信使用自定义char_traits
是可能的。不就是为了这个吗?
@MooingDuck:可能,但是您不需要使用这些特征的新std::basic_string
实例化吗?需要复印吗? (好吧,你可以让字符串最初使用这些特征,但这肯定会违反POLS)或者特征是比较的特征吗?我忘记了。
你说得对,它是一个需要副本的新类。替换它们快得多,或者如您所说使用自定义比较。我也认为它更容易出错。无论哪种方式都需要权衡。【参考方案3】:
有几种可能性,取决于您是否想要这种行为:
一次 在类中编码如果您想行为一次:只需使用您自己的(自定义)算法:
bool isSpace(char i) return i == '-' or i == ' ';
int compare(std::string const& left, std::string const& right)
typedef std::string::const_iterator ConstIterator;
typedef std::pair<ConstIterator, ConstIterator> Result;
size_t const size = std::min(left.size(), right.size());
Result const r = std::mismatch(left.begin(),
left.begin() + size,
right.begin(),
[](char a, char b)
return a == b or (isSpace(a) and isSpace(b));
);
if (r.first == left.begin() + size) // equal up til the end, shorter wins
return left.size() < right.size() ? -1 :
(left.size() == right.size() ? 0 : 1);
// not equal until the end
return *r.first < *r.second ? -1 : 1;
如果此行为需要在类本身中进行编码,您需要使用basic_string
并提供自定义特征类。
traits 类提供了一个 static int compare ( const char_type* s1, const char_type* s2, size_t n);
函数,供 std::string::compare
在后台使用。
例如:
struct MyTraits: char_traits<char> // too lazy to reimplement everything
static int compare(const char_type* s1, const char_type* s2, size_t n);
// definition can be trivially derived from the above version
;
typedef std::basic_string<char, MyTraits> MyString;
当然,MyString
与其他std::string
完全不兼容。
坦率地说,如果可以的话,只需“规范化”您的字符串并决定是使用 '-' 还是 ' '。它会让你的生活更轻松。
【讨论】:
我真的别无选择,我必须处理'-',因为这是我们数据库中名称条目中使用的,但是我们的分析在设置运行时不使用它们,所以我需要我的软件来识别这一点,例如。 PC-Eff T-P 是 PC Eff T P 的等价物,因为它认为它是浊度:P @John:在设计典型架构时,反复出现的一点是将数据的外部表示“调整”为自定义的内存表示。例如,DB 层可以简单地将 '-' 替换为 ' ' ,因为记录被拉入,然后你所有的烦恼都会消失。这种输入的验证/规范化很常见:) 我希望std::basic_string
可以从具有不同字符/特征/分配器的std::basic_string
隐式构造。这会简化很多事情。
@MooingDuck:我一般不是隐式构造函数的忠实拥护者,但在这种特殊情况下,我可能会受到诱惑:)【参考方案4】:
一种简单的方法是折叠字符串,即在比较它们之前简单地将所有“-”替换为“”。
【讨论】:
【参考方案5】:标准 C++ 库为此提供了强大的算法。似乎您想将 std::mismatch()
与自定义谓词一起使用,考虑到 '-' 和 ' ' 是相同的。这看起来像这样:
bool pred(char c0, char c1)
return c0 == c1
|| (c0 == '-' && c1 == ' ')
|| (c0 == ' ' && c1 == '-');
std::string const& s(s0.size() < s1.size()? s0: s1);
std::string const& l(s0.size() < s1.size()? s1: s0);
auto p = std::mismatch(s.begin(), s.end(), l.begin(), pred);
接着,p
是一对迭代器,指向不同的第一个字符(或结束迭代器)。要确定在您评估结果之前或之后的字符串排序。
接口有点烦人,因为需要先用较短的序列:两端都应该有约束。
【讨论】:
【参考方案6】:(社区维基,请随意贡献。)
您可以基于新的 char 类型定义新的字符串类型。以下编译并似乎运行,但可能有一些东西丢失或错误。目标是定义一个字符串类,其中连字符会自动转换为空格。
#include<iostream>
using namespace std;
struct newchar
char c;
bool operator <(const newchar &other) const
return this->c < other.c;
newchar(char c_): c(c_)
fixme();
newchar(): c('\0')
newchar & operator = (const newchar &in)
this->c = in.c;
fixme();
return *this;
void fixme()
if(c=='-')
c = ' ';
;
struct newstring : basic_string<newchar>
string toCharString() const
std :: string s;
for(const_iterator i = this->begin(); i != this->end(); i++)
char c = i->c;
s += c;
return s;
;
ostream& operator<< (ostream & os, const newstring &ns)
os << ns.toCharString();
return os;
int main()
newstring s;
s.compare(s);
s += 'k';
cout << '<' << string() << '>' << endl;
cout << '<' << s << '>' << endl;
【讨论】:
以上是关于如何为字符串类比较分配'-'等于'',这可能吗?的主要内容,如果未能解决你的问题,请参考以下文章