« Pythonでcircular doubly linked list |Main| 新年会日記 »

« Pythonでcircular doubly linked list | Python | PythonとJavaScriptの微妙な違い »

circular doubly linked listを使って0/1配列を省メモリ実装

もちろんPythonを使っているので定数倍くらいのディスアドバンテージはありますが。 要素のほとんどが0で、少しだけ1であるようなサイズNの配列を、 素直に普通の配列として実装するとNのオーダーのメモリを消費します。 そこで1の入っている部分だけを双方向リストで実装してメモリが節約しよう、というアルゴリズム。 西尾泰和のブログ: Pythonでcircular doubly linked listの続編。
# -*- coding: cp932 -*-
from circularDoublyLinkedList import DList

# DListを使って巨大な0/1配列をエミュレートする

class Array(DList):
    def __init__(self, size):
        self.size = size
        DList.__init__(self)

    def get(self, index):
        "index番目の要素の値を返す"
        for x in self:
            if x.value == index:
                return 1
            if x.value > index:
                return 0

    def set(self, index, value):
        "index番目の要素の値を設定する"
        if value:
            self.turnOn(index)
        else:
            self.turnOff(index)

    def turnOn(self, index):
        "index番目の要素の値を1にする"
        for x in self:
            if x.value == index:
                # すでに1になっている
                return
            if x.value > index:
                # indexより大きい最小の数の手前に要素を追加
                self.addBefore(index, x)
                return
        # indexより大きい数はない→末尾に追加
        self.addTail(index)

    def turnOff(self, index):
        "index番目の要素の値を0にする"
        e = self.find(index)
        if e:
            self.delete(e)
        else:
            # そんな要素はない→すでに0だった
            pass
            
    def __str__(self):
        result = ["0"] * self.size
        for x in self:
            result[x.value] = "1"

        return "[%s]" % "".join(result)

xs = Array(10)
print xs #=> [0000000000]
xs.set(5, 1)
xs.set(3, 1)
xs.set(7, 1)
print xs #=> [0001010100]
xs.set(3, 1)
print DList.__str__(xs) #=> [3, 5, 7]
xs.set(5, 0)
print xs #=> [0001000100]

トラックバック(Trackback)

Trackback URL: http://www.nishiohirokazu.org/mt/mt-tb.cgi/482

ご意見・ご感想をお送りください(フィードバック)

(フィードバックはメールで送信され、基本的に表示されませんが、内容によっては公開させていただくこともございます。ご了承ください。Your comment doesn't appear the page immediately. If the comment has value to other people, it will be put on the page or subsequent entries. Thank you.)

上の情報は、いずれも未記入でかまいません。 All of above questions are optional.