Ruby 创建任意字符层次结构

Ruby 创建任意字符层次结构,ruby,string,compare,Ruby,String,Compare,假设我有4个字符,A、p、B、N。我希望能够比较它们,以便: A>p>B>N>A 在Ruby中如何实现这一点?一个可能的解决方案是创建一个类,例如使用字符和权重或其他东西。并在其中实现运算符(方法) 别忘了将Comparablemixin包含在这个类中 class ComparableCharacter include Comparable attr_accessor :character, :weight def <=>(another) weight <

假设我有4个字符,A、p、B、N。我希望能够比较它们,以便:

A>p>B>N>A


在Ruby中如何实现这一点?

一个可能的解决方案是创建一个类,例如使用
字符
权重
或其他东西。并在其中实现
运算符(方法)

别忘了将
Comparable
mixin包含在这个类中

class ComparableCharacter
  include Comparable
  attr_accessor :character, :weight

  def <=>(another)
    weight <=> another.weight
  end
end
类可比字符
包括可比
属性访问器:字符,:权重
def(另一个)
重量,重量
结束
结束

当然,这不适用于您的示例,因为您的顺序不好-您永远不会有a>p>a,但至少它显示了如何根据您想要的顺序进行排序。

从您的注释中,似乎您并没有试图将这些元素按顺序排列,而是定义了其中一些元素之间的二进制关系。在Ruby中可以通过多种方式实现这一点,这取决于您以后打算如何使用这种关系

最简单的方法就是定义相关元素的有序对:

MAP = [
  ['A', 'P'],
  ['P', 'B'],
  ['B', 'N'],
  ['N', 'A']
]
然后在需要“比较”两个元素时使用它

def beats? one, other
  MAP.member?([one, other])
end

beats? 'A', 'B'
# => false 
beats? 'A', 'P'
# => true 
beats? 'N', 'A'
# => true 
另外,您可以使用以下命令从字符串生成地图

MAP = 'APBNA'.chars.each_cons(2).to_a

如果有人感兴趣,这是我的建议(三元比较-因为比较不是二进制操作!!!):

类剪刀
项目=%W(A P B N)
定义自我比较(项目、其他项目)
新建(项目)。比较其他项目
结束
def初始化(项目)
#输入验证?
@项目=项目
结束
def比较(其他_项)
#输入验证?
索引\u减法=项目。索引(@item)-项目。索引(其他项目)
减法
当1,-1
-减法
其他的
减法0
结束
结束
结束
需要“测试/单元”
包含MiniTest::断言
断言等于剪刀。比较('A','A'),0
断言等于剪刀。比较('P','P'),0
断言等于剪刀。比较('B','B'),0
断言等于剪刀。比较('N','N'),0
断言等于剪刀。比较('A','P'),1
断言等于剪刀。比较('P','A'),-1
断言等于剪刀。比较('P','B'),1
断言等于剪刀。比较('B','P'),-1
断言等于剪刀。比较('B','N'),1
断言等于剪刀。比较('N','B'),-1
断言等于剪刀。比较('N','A'),1
断言等于剪刀。比较('A','N'),-1

解释 相等:(A,A)比较

  • 指标:iA:0;iA:0
  • iA-iA=0
  • A等于A,因此我们可以返回0
  • 多数票:(A,p)

  • 指标:iA:0;iP:1
  • iA-iP=-1
  • A>P,所以我们必须得到1;我们可以使用
    -
    函数:
    -(-1)->1
  • 少数民族:(p,A)

  • 指标:iP:1;iA:0
  • iP-iA=1
  • P-
  • 功能:
    -(1)->-1
    边缘情况1:(N,A)

  • 索引:iN:3,iA:0
  • iN-iA=3
  • N>A,所以我们必须得到1;我们可以使用
    功能:
    (3 0)->1
  • 边缘情况2:(A,N)

  • 索引:iA:0,iN:3
  • iA-iN=-3
  • A
  • 功能:
    (3 0)->1

    其余的是重构:
    0
    可以通过
    函数转换为
    0

    那么,“大于”在您的情况下不是传递运算符?那么A和B是如何比较的呢?不,我想这是一个“循环”层次结构。嗯。。。如果A处于循环层次结构中,你如何确定A是否大于N?我猜这个想法类似于当时的“石头剪刀”关系,但“比较”一词是误导性的。比较是二元的。。。因此,这取决于您将其与哪个进行比较。您可以在
    排序方式中使用
    数组#索引
    @MladenJablanović,而不是创建临时映射。您确定这样实现不会影响性能吗?当然可以,但实现会更简单。:)还有另一个想法:
    Hash['APBN.chars.with_index.to_a]
    您违反了Ruby约定。当涉及变量时,它应该是snake_情况,而不是camelCase情况。映射映射到哈希比映射到数组更好。如果需要一个元素“击败”多个其他元素,则除外。无论如何,让我们把它留给读者作为练习
    MAP = 'APBNA'.chars.each_cons(2).to_a
    
    class RockPaperScissors
    
      ITEMS = %W(A P B N)
    
      def self.compare(item, other_item)
        new(item).compare other_item
      end
    
    
      def initialize(item)
    
        # input validations?
    
        @item = item
      end
    
      def compare(other_item)
    
        # input validations?
    
        indexes_subtraction = ITEMS.index(@item) - ITEMS.index(other_item)
    
        case indexes_subtraction
        when 1, -1
          - indexes_subtraction
        else
          indexes_subtraction <=> 0
        end
    
      end
    
    end
    
    require 'test/unit'
    include MiniTest::Assertions
    
    assert_equal RockPaperScissors.compare('A', 'A'), 0
    assert_equal RockPaperScissors.compare('P', 'P'), 0
    assert_equal RockPaperScissors.compare('B', 'B'), 0
    assert_equal RockPaperScissors.compare('N', 'N'), 0
    assert_equal RockPaperScissors.compare('A', 'P'), 1
    assert_equal RockPaperScissors.compare('P', 'A'), -1
    assert_equal RockPaperScissors.compare('P', 'B'), 1
    assert_equal RockPaperScissors.compare('B', 'P'), -1
    assert_equal RockPaperScissors.compare('B', 'N'), 1
    assert_equal RockPaperScissors.compare('N', 'B'), -1
    assert_equal RockPaperScissors.compare('N', 'A'), 1
    assert_equal RockPaperScissors.compare('A', 'N'), -1