【问题标题】:Is there a CompareTo method in C++ similar to Java where you can use > < = operations on a data typeC++ 中是否有类似于 Java 的 CompareTo 方法,您可以在其中对数据类型使用 > < = 操作
【发布时间】:2013-11-29 02:25:07
【问题描述】:

我知道在 java 中有一个 compareTo 方法,您可以在一个类中编写该方法,该方法将比较两个变量并返回一个值 -1、1 或 0,表示大于、小于和等于操作。有没有办法在 C++ 中做到这一点?

背景: 我创建了一个修改过的字符串类,其中它需要一个字符串和一个数组列表。我希望能够以传统方式比较字符串,如果它在字母表中较低,它将小于,高于它将大于。比我只想将数组列表链接到文件以存储在文本文件中索引单词的页面。无论如何,细节并不重要,因为我已经写好了课程。我只需要创建可用于我的 cpp 文件的主文件或其他数据类型(例如各种树)的 compareTo 方法。

我知道如何用 java 编写代码,也许有人可以帮助我使用 C++ 语法(不幸的是,我需要为这个项目用 C++ 编写,而且我是 C++ 新手)

我将缩短代码以给出我在做什么的粗略轮廓,而不是像我在 java 中所知道的那样编写 compareTo 方法

class name ModifiedString
Has variables: word , arraylist pagelist
Methods: 
getWord (returns the word associated with the class, i.e its string)
appendPageList (adds page numbers to the array list, this doesnt matter in this question)

我将如何在 java 中做到这一点

int compareTo(ModifiedString a){
  if(this.getWord() > a.getWord())
      return 1;
  else if (this.word() < a.getWord())
      return -1;
  else return 0;
}

那么当 或 == 在 ModifiedWord 上使用时,这些操作将是有效的。

【问题讨论】:

  • 读取操作符重载。
  • 我实际上将使用向量而不是数组列表,因为在 C++ 中没有像 java 中那样的数组列表定义。
  • 先决定语言。标题说 C,它没有运算符重载。
  • 您的 java 方法不正确,您比较的是地址值而不是实际字符串

标签: c++ class compare string-comparison


【解决方案1】:

std::string 已经包含operator&lt; 的工作重载,因此您可以直接比较字符串。 Java 使用compareTo 主要是因为内置的比较运算符产生的结果通常对字符串没有用处。作为一种低级语言,Java 不支持用户定义的运算符重载,因此它使用compareTo 作为创可贴来弥补语言的不足。

但是,根据您的描述,您根本不需要直接处理任何。至少正如您所描述的问题,您真正想要的是:

std::map<std::string, std::vector<int> > page_map;

然后,您将从文本文件中读取单词,并将每个单词出现的页码插入到页面映射中:

page_map[current_word].push_back(current_page);

请注意,我在上面使用了std::map,期望您可能需要有序的结果(例如,能够按字母顺序快速找到从ageale 的所有单词)。如果您不关心订购,您可能想改用std::unordered_map

编辑:这是一个简单的文本交叉引用程序,它读取一个文本文件(从标准输入)并按行号(即每个“单词”,以及它所在的行号)写出一个交叉引用。词出现)。

#include <map>
#include <unordered_map>
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <iterator>
#include "infix_iterator.h"

typedef std::map<std::string, std::vector<unsigned> > index;

namespace std {
ostream &operator<<(ostream &os, index::value_type const &i) { 
    os << i.first << ":\t";
    std::copy(i.second.begin(), i.second.end(),
        infix_ostream_iterator<unsigned>(os, ", "));
    return os;
}
}

void add_words(std::string const &line, size_t num, index &i) { 
    std::istringstream is(line);
    std::string temp;

    while (is >> temp)
        i[temp].push_back(num);
}

int main() { 
    index i;
    std::string line;
    size_t line_number = 0;

    while (std::getline(std::cin, line))
        add_words(line, ++line_number, i);

    std::copy(i.begin(), i.end(), 
        std::ostream_iterator<index::value_type>(std::cout, "\n"));
    return 0;
}

如果您查看第一个 typedefindex),如果您想测试哈希表与红黑树,可以将其从 map 更改为 unordered_map。请注意,这对“单词”的解释非常松散——基本上是任何非空白字符序列,例如,它将example, 视为“单词”(它将与example 分开)。

请注意,这使用了我发布的 infix_iterator elsewhere

【讨论】:

  • 这实际上对我来说很有意义,而不是创建一个以这种方式将向量映射到字符串的整个类。因此,在这种情况下,我会将映射(字符串和向量)添加到树或哈希表(这是我想要做的)而不是当我执行查找操作时(在这种情况下,我将其定义为返回数据)它将返回一张地图。我可以从中访问页面。但是,在树中进行比较时,地图会比较字符串还是向量?在这个练习中,我需要做的几乎所有事情就是使用不同的树上出现的页码索引来存储单词
  • 为什么要将地图添加到树或哈希表中? map 一棵树(unordered_map 是一个哈希表)。它已经将您直接从单词带到页码。
  • 我已经构建了 redblacktree、binarytree、hashtable、chainedhashtable 和其他一些数据结构。所有这些都有自己的添加、删除和查找,它们带有参数 T x,因此可以在任何情况下使用。这就是为什么我虽然创建自己的存储字符串和数组的数据类型是最好的选择,但我不知道如何比较。这个想法是使用这些数据结构中的每一个来索引单词(所以我可以在这之间进行更改而不是观察每个数据结构的运行时间)并添加一个与存储它出现的页码的单词相关的数组。跨度>
  • @user2665682:只需使用&lt; 进行比较,就像在if (string1 &lt; string2)... 中一样,我可能会写其他人(在外部)像std::map 一样工作,这使得替换变得容易。
  • 好的,所以在我的 ModifiedString 中应该如何比较修改后的字符串 .getWord (返回一个字符串)所以可以说我有一个修改过的字符串的测试,然后我可以调用 if(string > test ) 其中 test 默认返回 test.getWord() 所以我不必每次都写 test.getWord 代替 test 因为我的其他数据结构不允许它。这种运算符重载的想法有点令人困惑,因为它对我来说是全新的。
【解决方案2】:

Sun 决定不在 Java 中包含运算符重载,因此他们提供了一种类内方式(通过成员函数)来完成这项工作:equals()compareTo() 函数。

C++ 有运算符重载,它允许您在自己的类型中指定语言运算符的行为。

要学习如何重载运算符,我建议你阅读这个帖子:Operator overloading

【讨论】:

    【解决方案3】:

    在 C++ 中,您可以直接定义 bool operator&lt;,无需发明有趣的名称,operator&lt;operator== 也是如此。它们通常被实现为带有一个额外参数的成员函数,即右侧,但您也可以将它们定义为带有两个参数的非成员函数。

    【讨论】:

    • " 它们通常被实现为成员函数,带有一个额外的参数,右侧," 我一直听说friend 非成员重载比成员,因为它允许您指定第一个非类操作数,如 this answer 解释。
    • @Manu343726:对于其他运营商来说,这更像是一个问题。 &lt; 通常没有非类左侧的重载。明显的例外是"" == std::string()
    【解决方案4】:

    在 C++ 中没有标准的方法来定义一个操作符,该操作符执行 Java compareTo() 函数所做的事情。但是,您可以实现

    int compareTo(const ModifiedString&, const ModifiedString&);
    

    另一种选择是重载 、>=、== 和 != 运算符,例如通过实施

    bool operator<(const ModifiedString&, const ModifiedString&);
    

    【讨论】:

    • 即使您建议使用类似于 Java 的解决方案(我的意思是第一个解决方案,compareTo() 方法),这不是 C++ 的工作方式,也请提供一个定义明确的解决方案:如果您实现二进制compareTo(),指定它应该是static,或者像Java 一样简单地实现一个成员单参数compareTo() 函数。请注意,这是一个建议,而不是批评。
    • C++ 中的规范名称是compare,如std::string::compare
    猜你喜欢
    • 2011-11-05
    • 2014-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多