如何从给定的一组值中进行选择,四舍五入?

时间:2017-08-17 15:11:46

标签: ruby math hashtable

我有一把带有两把钥匙的红宝石阵列,' tier'和'价格'。对于给定的价格,我想返回该等级。

这很简单,具有完全匹配,但如何通过将输入值四舍五入到数组中的下一个值来确保总是匹配?

例如,根据下面的数组,如果我的值为' 499',我想返回' 10'。

tiers = [
    { tier: 0, price: 0 },
    { tier: 1, price: 50 },
    { tier: 2, price: 100 },
    { tier: 3, price: 150 },
    { tier: 4, price: 200 },
    { tier: 5, price: 250 },
    { tier: 6, price: 300 },
    { tier: 7, price: 350 },
    { tier: 8, price: 400 },
    { tier: 9, price: 450 },
    { tier: 10, price: 500 },
    { tier: 11, price: 550 },
    { tier: 12, price: 600 },
    { tier: 13, price: 650 },
    { tier: 14, price: 700 },
    { tier: 15, price: 750 },
    { tier: 16, price: 800 },
    { tier: 17, price: 850 },
    { tier: 18, price: 880 },
    { tier: 19, price: 950 },
    { tier: 20, price: 1000 }
]

我可以与tiers.detect { |tier| tier[:price] == "500"}[:tier]完全匹配,但如果我没有匹配,则会返回错误。我可以增加我的输入值,直到我返回一个匹配但这看起来非常低效。

我考虑过舍入我的输入值,但您注意到增量并不总是相同的(从第17层到第18层,价格仅增加30)。

3 个答案:

答案 0 :(得分:6)

您可以成对枚举所有等级,并根据货币对评估您的价格。像这样:

#Import necessary modules

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

class MainWindow(QMainWindow, QWidget):

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.initUI()

    def hex_color(self, color): #Changes hex color to Q color
        r = int(color[0:2], 16)
        g = int(color[0:2], 16)
        b = int(color[0:2], 16)
        return QColor(r, g, b)

    def Center(self):  #Moves window to center
        Retrieve_Geometry = self.frameGeometry()
        Center_Screen = QDesktopWidget().availableGeometry().center()
        Retrieve_Geometry.moveCenter(Center_Screen)
        self.move(Retrieve_Geometry.topLeft())

    def Example_Pix(self):
        label = QLabel()
        pixmap = QPixmap('icon2.png')
        label.setPixmap(pixmap)


    def initUI(self):
        self.setWindowTitle("bear GUI")
        self.setGeometry(850, 850, 850, 850)
        self.Center()
        self.Example_Pix()
        self.show()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    ex = MainWindow()
    sys.exit(app.exec())

答案 1 :(得分:1)

如果数组很大,使用 find-minimum mode 是明智的  方法Array#bsearch_index,它将时间复杂度从O(n)减少到顺序搜索到O(log n)。

我假设:pricetiers的值正在增加,如果测试价格超过nil,则会返回tiers.last[:price]

def round_up(tiers, price)
  return nil if price > tiers.last[:price]
  tiers[tiers.map { |h| h[:price] }.bsearch_index { |p| p >= price }][:tier]
end

试试吧。

tiers = [
  { tier: "cat", price:   0 },
  { tier: "dog", price:  50 },
  { tier: "pig", price: 100 },
  { tier: "owl", price: 150 },
  { tier: "ram", price: 300 }
]

round_up(tiers, -10) #=> "cat"
round_up(tiers,   0) #=> "cat"
round_up(tiers,   1) #=> "dog"
round_up(tiers,  49) #=> "dog"
round_up(tiers,  50) #=> "dog"
round_up(tiers,  51) #=> "pig"
round_up(tiers, 150) #=> "owl"
round_up(tiers, 250) #=> "ram"
round_up(tiers, 300) #=> "ram"
round_up(tiers, 301) #=> nil

答案 2 :(得分:0)

tiers.detect{|x| x[:price] >= <required_number>}[:tier]
如果层的结构是给定的,

可以工作。

虽然不处理边界条件。

tiers.detect{|x| x[:price] >= 1}[:tier] #=> 1
tiers.detect{|x| x[:price] >= 100}[:tier] #=> 2
tiers.detect{|x| x[:price] >= 499}[:tier] #=> 10
tiers.detect{|x| x[:price] >= 750}[:tier] #=> 15