問題2.1
昨日、作りながら寝落ちしたので、昼休みに残り完成。
時間切れなので、発展問題は検討すらしてないです。
問題
ソートされていない連結リストから、重複する要素を削除するコードを書いてください。
発展問題
もし、一時的なバッファが使用できないとすれば、どうやってこの問題を解きますか?
pylist.py (短方向連結リスト)
#encoding: utf-8 class Cell: ''' リストを構成するセルを表すクラス >>> cell = Cell(5) >>> print cell.get_data() 5 >>> print cell.get_next() None >>> cell.set_data('a') >>> print cell.get_data() a >>> cell.set_next(10) >>> print cell.get_next() 10 ''' def __init__(self, data, next=None): self.data = data self.next = next # セルのデータ取得 def get_data(self): return self.data # セルが指す次のセルのポインタ取得 def get_next(self): return self.next # セルのデータを更新 def set_data(self, data): self.data = data # セルが指す次のセルのポインタ更新 def set_next(self, next): self.next = next class LinkedList: ''' 連結リストクラス >>> linked_list = LinkedList() >>> linked_list.get_top() >>> linked_list.insert(0, 100) >>> print linked_list.index(100) 0 >>> linked_list.get_top().get_data() 100 >>> linked_list.insert(1, 200) >>> print linked_list.index(200) 1 >>> linked_list.insert(1, 150) >>> print linked_list.index(150) 1 >>> print linked_list.index(200) 2 >>> linked_list.delete(2) True >>> linked_list.index(200) -1 >>> linked_list.index(150) 1 >>> linked_list.delete(0) True >>> linked_list.index(150) 0 >>> linked_list.delete(0) True >>> linked_list.delete(0) False ''' def __init__(self): self.top = None # リストの先頭セルを取得 def get_top(self): return self.top # dataに示すデータがリストの何番目かを取得 def index(self, data): offset = 0 cell = self.top while cell: if cell.get_data() == data: return offset offset += 1 cell = cell.get_next() return -1 # リストのoffset番目にdataを格納 def insert(self, offset, data): # offsetが0もしくはリストが空の時 if offset == 0 or not self.top: self.top = Cell(data, self.top) else: cell = self.top while cell.get_next(): offset -= 1 if offset == 0: break cell = cell.get_next() # 新たにセルを作成し、リストに挿入する added_cell = Cell(data, cell.get_next()) cell.set_next(added_cell) # リストのoffset番目を削除 def delete(self, offset): # リストの先頭を削除 if offset == 0: # リストにデータが1つ以上ある if self.top: self.top = self.top.get_next() return True else: return False else: cell = self.top while cell.get_next(): offset -= 1 if offset == 0: # 対象のセルをリストから外す cell.set_next(cell.get_next().get_next()) return True cell = cell.get_next() return False def _test(): import doctest doctest.testmod() if __name__ == '__main__': _test()
2-1.py (重複の削除)
#encoding: utf-8 from pylist import Cell from pylist import LinkedList def erase_duplication(linked_list): ''' リスト中の重複セルを削除 >>> linked_list = LinkedList() >>> linked_list.insert(0, 100) >>> linked_list.insert(1, 200) >>> linked_list.insert(2, 300) >>> linked_list.insert(3, 200) >>> linked_list.insert(4, 100) >>> linked_list.insert(5, 500) >>> linked_list.index(500) 5 >>> erase_duplication(linked_list) >>> linked_list.index(500) 3 ''' # 重複セルチェック用のハッシュテーブル hash_table = {} # 重複セルのチェック counter = 0 cell = linked_list.get_top() while cell.get_next(): # 重複セルは削除 if cell.get_data() in hash_table: # 重複セルを削除する前に、次のセルを指定 cell = cell.get_next() linked_list.delete(counter) counter -= 1 else: hash_table[cell.get_data()] = True cell = cell.get_next() counter += 1 # リストの最後のセルの処理 if cell.get_data() in hash_table: linked_list.delete(counter + 1) def _test(): import doctest doctest.testmod() if __name__ == '__main__': _test()