如何为字符串类比较分配'-'等于'',这可能吗?

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;

【讨论】:

以上是关于如何为字符串类比较分配'-'等于'',这可能吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何为numpy数组中的特定行和列分配字符串值?

如何为类赋值并创建json

如何为一组边分配相同的样式?

如何为地图创建自己的比较器?

如何为 Azure 移动应用表设置架构?

如何为 sbt/play 禁用彩色终端输出?