首页 > 解决方案 > 如何从长字符串中的一组指令中绘制路径

问题描述

3周前刚开始学习python,到目前为止,我基本上能够理解课堂上给出的信息。现在我真的在过去一周的这个任务中遇到了麻烦。每天花费无数小时搜索、阅读、索引文档、GitHub 和其他源材料并尝试将其作为代码的一部分。有时您只是不知道自己在寻找什么,这真的很难。

我仍然无法弄清楚如何完成这个类似于海龟图形的程序。但是我们不允许使用 turtle 模块。

我基本上需要创建一个算法来从很长的字符串中绘制路径。(类似于乌龟)

代码必须从初始位置向新位置添加一行。对于 x = 0 ,y = 0,初始起始位置是 (x,y)

这是给定的字符串。

AAAAADADAAGAAAAAAAAAAGAADAAAAAAAAAAAAAAAA TDDAAAGATADAAADADAAA TDAAADATAGAAAGAGAAA TADAATAAGAAGAAGAA TAAATAAGAAGAAGAA TDDAAAGADTADAAADADAAA TATAAADADAAADA TAAAAGADTAGAAGA TDAGGTAAAAAA DA​​AAAAAAAA DA​​AAAAA TGGADTAGAAGA TDADTAGAAAGAGA TDAAAAAAAAA DTAGAGAAAGA

我在纸上做了很多思考,试图弄清楚如何处理它,是的,我理解了 4 个可能方程的算法。但我只是在努力理解如何解决这些问题以及可以在 python 中完成这些代码的技巧。

至此,任务结束,今天到期。如果有人可以分享如何解决/解决这个问题,我真的很感激,我真的很想了解如何解决这些问题。否则,我将永远无法完全理解我的下一个作业,也无法将更多时间花在不同的课堂作业上。

谢谢

这段代码是我所做的众多代码之一,但这段代码代表了我正在尝试做的事情。

def get_E0(x,y):        ###UP
    return x, y+1

def get_E1(x,y):        ###RIGHT
    return x+1, y

def get_E2(x,y):        ###DOWN
    return x, y-1

def get_E3(x,y):        ###LEFT
    return x-1 ,y


def get_DADE0(i,x,y):                     ### Def for every possible left or right turn
    for letters in b[i]:                  ### Trying to work with the sliced list  
        if letters == 'A':                ### For every possible left or right turn                
            x,y = get_E0(x,y)             ### Was hoping to introduce a counter 
            if i % 2 == 0:                ### for each index list in b
                get_outAppend(outX,outY,x,y)
            b[i] = b[i].lstrip('A')
        if letters == 'D':
            b[i] = b[i].lstrip('D')
            break
    return x,y,b

def get_DADE1(i,x,y):
    for letters in b[i]:
        if letters == 'A':
            x,y = get_E1(x,y)
            if i % 2 == 0:
                get_outAppend(outX,outY,x,y)
            b[i] = b[i].lstrip('A')
        if letters == 'D':
            b[i] = b[i].lstrip('D')
            break
    return x,y,b
       
   
def get_DADE2(i,x,y):
    for letters in b[i]:
        if letters == 'A':
            x,y = get_E2(x,y)
            if i % 2 == 0:
                get_outAppend(outX,outY,x,y)
            b[i] = b[i].lstrip('A')
        if letters == 'D':
            b[i] = b[i].lstrip('D')
            break
    return x,y,b   
    
     
   
def get_DADE3(i,x,y):
    for letters in b[i]:
        if letters == 'A':
            x,y = get_E3(x,y)
            if i % 2 == 0:
                get_outAppend(outX,outY,x,y)
            b[i] = b[i].lstrip('A')
        if letters == 'D':
            b[i] = b[i].lstrip('D')
            break
    return x,y,b                
    

def get_GAGE0(i,x,y):
    
    for letters in b[i]:
        if letters == 'A':
            x,y = get_E0(x,y)
            if i % 2 == 0:
                get_outAppend(outX,outY,x,y)
            b[i] = b[i].lstrip('A')
        if letters == 'G':
            b[i] = b[i].lstrip('G')
            break
    return x,y,b                
    

def get_GAGE1(i,x,y):
    
    for letters in b[i]:
        if letters == 'A':
            x,y = get_E1(x,y)
            if i % 2 == 0:
                get_outAppend(outX,outY,x,y)
            b[i] = b[i].lstrip('A')
        if letters == 'G':
            b[i] = b[i].lstrip('G')
            break
    return x,y,b    
    
def get_GAGE2(i,x,y):
    
    for letters in b[i]:
        if letters == 'A':
            x,y = get_E2(x,y)
            if i % 2 == 0:
                get_outAppend(outX,outY,x,y)
            b[i] = b[i].lstrip('A')
        if letters == 'G':
            b[i] = b[i].lstrip('G')
            break
    return x,y,b    
    

def get_GAGE3(i,x,y):
    
    for letters in b[i]:
        if letters == 'A':
            x,y = get_E3(x,y)
            if i % 2 == 0:
                get_outAppend(outX,outY,x,y)
            b[i] = b[i].lstrip('A')
        if letters == 'G':
            b[i] = b[i].lstrip('G')
            break
    return x,y,b     
    

a = str('AAAAADADAAGAAAAAAAGAADADAAAAADAAAAAAAAATDDAAAGATADAAADADAAATDAAADATAGAAAGAGAAATDADAATAAGAAGAAGAATAAATAAGAAGAAGAATDDAAAGADTADAAADADAAATATAAADADAAADATDAAAAGADTAGAAGATDAGGTAAAAAADAAAAAAAAADAAAAAATGGADTAGAAGATDADTAGAAAGAGATDAAAAAAAAADTAGAGAAAGA')

b = a.split('T')
x = 0                                   ### starting values for x,y
y = 0
outX, outY = [0], [0]                   ### List to append coordinates  


while True:                             ### Here I was trying to see if the loops would work as intended
                                        ### 
    x,y,b = get_DADE0(0,x,y)    #up
    x,y,b = get_DADE1(0,x,y)    #right
    x,y,b = get_GAGE2(0,x,y)    #down
    x,y,b = get_GAGE1(0,x,y)    #right
    x,y,b = get_DADE0(0,x,y)    #up
    x,y,b = get_DADE1(0,x,y)    #right
    x,y,b = get_DADE2(0,x,y)    #down
    x,y,b = get_DADE3(0,x,y)    #left
    
    x,y,b = get_DADE0(1,x,y)
    x,y,b = get_DADE1(1,x,y)
    x,y,b = get_GAGE0(1,x,y)
    x,y,b = get_DADE1(1,x,y)
    
    x,y,b = get_DADE2(2,x,y)
    x,y,b = get_DADE3(2,x,y)
    x,y,b = get_DADE0(2,x,y)
    x,y,b = get_DADE1(2,x,y)
    x,y,b = get_GAGE0(2,x,y)
    x,y,b = get_GAGE3(2,x,y)
    x,y,b = get_DADE2(2,x,y) 
    break



    
    
plt.axis('equal')                  ### Plotting my figure.
plt.axis([0,7,0,10])
plt.plot(outX,outY, color = 'r')


标签: pythonpython-3.x

解决方案


你似乎在你的任务中付出了很多努力。您正在寻求如何解决此类问题的提示和技巧,因此我不想立即为您提供完整的解决方案,而是想提供一个可能的策略,如何逐步构建解决方案。

与其事先尝试根据笔是向上还是向下来拆分字符串,而是更容易地循环整个字符串并在字符串中遇到“T”时处理它们。毕竟,笔向上或向下的唯一区别是我们是否应该存储当前位置以进行绘图。这意味着您的代码的主要部分看起来像。

for command in a:
    # do something with command

这里command可以是移动(“A”)、旋转(“G”或“D”)或线切换(“T”)。第一个命令,“A”将根据海龟的当前位置和移动方向更新海龟的位置,“G”和“T”将更新海龟移动的方向。切换命令将改变是否笔向上或向下。这意味着海龟的状态可以通过三个参数来描述:当前位置 、(x,y)海龟移动的方向(u, v)、以及用于描述笔当前是向上还是向下的布尔值is_pen_down。最初,乌龟位于(0,0),我假设它正向 y 方向移动,即(u, v) == (0, 1)。笔最初是向下的。考虑到这一点,

x, y = (0, 0)
u, v = (0, 1)
is_pen_down = True
for command in a:
    if command == 'A':
        # move forward
    elif command == 'G':
        # rotate left
    elif command == 'D':
        # rotate right
    elif command == 'T':
        # update pen

下一步是确定海龟的新位置和方向。

根据任务,“A”将把乌龟向前移动一步。这意味着如果(x, y)是当前位置和(u, v)当前方向,则新位置将是(x+u, y+v)。方向将保持不变。

'D' 会将乌龟向右旋转 90 度。在矢量符号中,这意味着新方向将是(v, -u)。在这种情况下,位置将保持不变。

类似地,'G' 会将海龟向左旋转 90 度,这意味着新方向将是(-v, u)

使用这些表达式,更新后的 for 循环如下所示:

x, y = (0, 0)
u, v = (0, 1)
is_pen_down = True
for command in a:
    if command == 'A':
        x += u
        y += v
    elif command == 'G':
        u, v = -v, u
    elif command == 'D':
        u, v = v, -u
    elif command == 'T':
        # update pen

剩下的就是切换笔和画线。为此,我们需要在笔放下时跟踪海龟的位置。这可以通过将当前的 x 和 y 位置附加到单独的列表中来完成,就像每次更新海龟的位置时,笔向下时一样。如果笔上升(即当命令等于'T'并且is_pen_down为真时),应该画线并且我们应该开始新的线。此外,当循环结束时,如果笔仍然向下,我们应该记住绘制当前行,并显示该图。这意味着最终程序将类似于:

import matplotlib.pyplot as plt

a = 'AAAAADADAAGAAAAAAAGAADADAAAAADAAAAAAAAATDDAAAGATADAAADADAAATDAAADATAGAAAGAGAAATDADAATAAGAAGAAGAATAAATAAGAAGAAGAATDDAAAGADTADAAADADAAATATAAADADAAADATDAAAAGADTAGAAGATDAGGTAAAAAADAAAAAAAAADAAAAAATGGADTAGAAGATDADTAGAAAGAGATDAAAAAAAAADTAGAGAAAGA'

x, y = (0, 0)
u, v = (0, 1)
is_pen_down = True
outX = [x]
outY = [y]
for command in a:
    if command == 'A':
        x += u
        y += v
    elif command == 'G':
        u, v = -v, u
    elif command == 'D':
        u, v = v, -u
    elif command == 'T':
        if is_pen_down:
            # pen about to go up
            plt.plot(outX, outY)
            outX = []
            outY = []
        # toggle pen
        is_pen_down = not(is_pen_down)
    if is_pen_down:
        outX.append(x)
        outY.append(y)

# after loop, if pen is down plot open line
if is_pen_down:
    plt.plot(outX, outY)

plt.show()

推荐阅读