本质上,我会将自己的解决方案基于递归。我将使用以下内容扩展容器类:
cursor_position
- 存储突出显示元素(或包含包含突出显示元素的元素的元素,或除此之外的任何级别的递归)的索引的属性。
repr_with_cursor
- 此方法应返回容器内容的可打印版本,已突出显示当前选定的项目。
mov_right
- 当光标向右移动时应该调用此方法。返回元素内光标的新索引,或者None
如果光标落在当前容器“外部”(如果您移过容器中的最后一个元素。
mov_left
- 同上,但向左。
递归应该工作的方式是,对于每种方法,根据突出显示的方法的类型,您应该有两种不同的行为:
- 如果光标在容器上,它应该调用“指向”容器的方法。
- 如果光标在非容器上,它应该执行“真实的事情”。
编辑
我有半个小时的空闲时间,所以我拼凑了一个示例类来实现我的想法。它的功能不完整(例如,当它到达最大容器的任一端时,它不能很好地处理,并且要求类的每个实例在最大序列中只使用一次),但它足以证明这个概念. 在人们对此发表评论之前,我将重复一遍:这是概念验证代码,它还没有准备好使用!
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class C(list):
def __init__(self, *args):
self.cursor_position = None
super(C, self).__init__(*args)
def _pointed(self):
'''Return currently pointed item'''
if self.cursor_position == None:
return None
return self[self.cursor_position]
def _recursable(self):
'''Return True if pointed item is a container [C class]'''
return (type(self._pointed()) == C)
def init_pointer(self, end):
'''
Recursively set the pointers of containers in a way to point to the
first non-container item of the nested hierarchy.
'''
assert end in ('left', 'right')
val = 0 if end == 'left' else len(self)-1
self.cursor_position = val
if self._recursable():
self.pointed._init_pointer(end)
def repr_with_cursor(self):
'''
Return a representation of the container with highlighted item.
'''
composite = '['
for i, elem in enumerate(self):
if type(elem) == C:
composite += elem.repr_with_cursor()
else:
if i != self.cursor_position:
composite += str(elem)
else:
composite += '**' + str(elem) + '**'
if i != len(self)-1:
composite += ', '
composite += ']'
return composite
def mov_right(self):
'''
Move pointer to the right.
'''
if self._recursable():
if self._pointed().mov_right() == -1:
if self.cursor_position != len(self)-1:
self.cursor_position += 1
else:
if self.cursor_position != len(self)-1:
self.cursor_position += 1
if self._recursable():
self._pointed().init_pointer('left')
else:
self.cursor_position = None
return -1
def mov_left(self):
'''
Move pointer to the left.
'''
if self._recursable():
if self._pointed().mov_left() == -1:
if self.cursor_position != 0:
self.cursor_position -= 1
else:
if self.cursor_position != 0:
self.cursor_position -= 1
if self._recursable():
self._pointed().init_pointer('right')
else:
self.cursor_position = None
return -1
一个简单的测试脚本:
# Create the nested structure
LevelOne = C(('I say',))
LevelTwo = C(('Hello', 'Bye', 'Ciao'))
LevelOne.append(LevelTwo)
LevelOne.append('!')
LevelOne.init_pointer('left')
# The container's content can be seen as both a regualar list or a
# special container.
print(LevelOne)
print(LevelOne.repr_with_cursor())
print('---')
# Showcase the effect of moving the cursor to right
for i in range(5):
print(LevelOne.repr_with_cursor())
LevelOne.mov_right()
print('---')
# Showcase the effect of moving the cursor to left
LevelOne.init_pointer('right')
for i in range(5):
print(LevelOne.repr_with_cursor())
LevelOne.mov_left()
它输出:
['I say', ['Hello', 'Bye', 'Ciao'], '!']
[**I say**, [Hello, Bye, Ciao], !]
---
[**I say**, [Hello, Bye, Ciao], !]
[I say, [**Hello**, Bye, Ciao], !]
[I say, [Hello, **Bye**, Ciao], !]
[I say, [Hello, Bye, **Ciao**], !]
[I say, [Hello, Bye, Ciao], **!**]
---
[I say, [Hello, Bye, Ciao], **!**]
[I say, [Hello, Bye, **Ciao**], !]
[I say, [Hello, **Bye**, Ciao], !]
[I say, [**Hello**, Bye, Ciao], !]
[**I say**, [Hello, Bye, Ciao], !]
有趣的问题!我今天最喜欢的操作系统问题!:)