理系母の趣味はプログラミング

理系院卒、メーカー技術職の二児の母が、PythonやVBAで色々と作ってアップしていくブログです。

基本情報技術者アルゴリズムの問題をPythonでコーディングしてみた【平成28年春】

過去問コーディング。
今回の問題は、簡易メモ帳プログラムです。

過去問PDF「出典:平成28年度 春期 基本情報技術者試験 午後 問8」

プログラム

#グローバル変数を定義
MemoCnt = 0
MemoMax = 5
Memo = ['']*MemoMax #リストが空だと要素番号で値を入れることがないため、枠を作っておく
DataLen = 0
DataMax = 25
Data = ['']*DataMax #枠を作っておく


def reset_memo():
    global MemoCnt, DataLen
    MemoCnt = 0
    DataLen = 0

def add_memo(text):
    global MemoCnt,Memo,DataLen,Data

    textLen = len(text)
    Memo[MemoCnt] = DataLen
    MemoCnt = MemoCnt + 1
    Data[DataLen] = textLen
    DataLen = DataLen + 1
    for i in range(textLen):
        Data[DataLen + i] = text[i]

    DataLen = DataLen + textLen

def delete_memo(pos):
    global MemoCnt,Memo

    i = pos+1
    while i < MemoCnt:
        Memo[i - 1] = Memo[i]
        i = i + 1

    MemoCnt = MemoCnt - 1

def change_memo(pos,text):
    global Memo,DataLen,Data

    textLen = len(text)
    Memo[pos] = DataLen
    Data[DataLen] = textLen
    DataLen = DataLen + 1
    for i in range(textLen):
        Data[DataLen + i] = text[i]

    DataLen = DataLen + textLen

def move_memo(fromPos,toPos):
    global Memo

    m = Memo[fromPos]
    if fromPos < toPos:
        for i in range(fromPos,toPos):
            Memo[i] = Memo[i+1]

    if fromPos > toPos:
        for i in range(fromPos,toPos,-1):
            #toPos+1→toPosに変更。range(a,b)はa=<i<bのため
            Memo[i] = Memo[i-1]

    Memo[toPos] = m

def print_ans():
    print(Memo)
    print(Data)
    print(MemoCnt)
    print(DataLen)

def clear_garbage():
    global Memo,DataLen,Data

    temp = ['']*DataMax

    DataLen = 0
    
    if MemoCnt == 0:
        return

    for m in range(MemoCnt):
        d = Memo[m]
        Memo[m] = DataLen
        for i in range(Data[d]+1): #Data[d]→Data[d]+1に変更
            temp[DataLen] = Data[d+i]
            DataLen = DataLen + 1

    for d in range(DataLen):
        Data[d] = temp[d]



print('実行例1')
reset_memo()
print_ans()

print('実行例2')
add_memo('Aoki')
add_memo('Imai')
add_memo('Uno')
add_memo('Endo')
print_ans()

print('実行例3')
delete_memo(0)
print_ans()

print('実行例4')
change_memo(2,'Abe')
print_ans()

print('実行例5')
move_memo(2,0)
print_ans()

print('設問2')
clear_garbage()
print_ans()

出力結果

実行例1
['', '', '', '', '']
['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
0
0
実行例2
[0, 5, 10, 14, '']
[4, 'A', 'o', 'k', 'i', 4, 'I', 'm', 'a', 'i', 3, 'U', 'n', 'o', 4, 'E', 'n', 'd', 'o', '', '', '', '', '', '']
4
19
実行例3
[5, 10, 14, 14, '']
[4, 'A', 'o', 'k', 'i', 4, 'I', 'm', 'a', 'i', 3, 'U', 'n', 'o', 4, 'E', 'n', 'd', 'o', '', '', '', '', '', '']
3
19
実行例4
[5, 10, 19, 14, '']
[4, 'A', 'o', 'k', 'i', 4, 'I', 'm', 'a', 'i', 3, 'U', 'n', 'o', 4, 'E', 'n', 'd', 'o', 3, 'A', 'b', 'e', '', '']
3
23
実行例5
[19, 5, 10, 14, '']
[4, 'A', 'o', 'k', 'i', 4, 'I', 'm', 'a', 'i', 3, 'U', 'n', 'o', 4, 'E', 'n', 'd', 'o', 3, 'A', 'b', 'e', '', '']
3
23
設問2
[0, 4, 9, 14, '']
[3, 'A', 'b', 'e', 4, 'I', 'm', 'a', 'i', 3, 'U', 'n', 'o', 'o', 4, 'E', 'n', 'd', 'o', 3, 'A', 'b', 'e', '', '']
3
13

【原文コードとの主な相違点】
・リスト型の変数について、あらかじめ枠を作るためのコードを追加。
・for ループの終値
【補足】
・設問2の出力結果を見ると、clear_garbage()実行後もData[13~22]の値が残っている。実は原文のプログラムでも同様にDataに残る。これでは一見、空き要素が増やせてないじゃん!と思われるが、DataLen=13になることで、メモとして参照されるのはData[0]~Data[12]までとなり、Data[13]~Data[22]は’空き要素’扱いになる。したがって、次にadd_memo()を実行すると、Data[13~]に上書きされる。

【感想】
これもほぼ問題文どおりです。
問題文通り過ぎて、プログラムをコピーしているだけの作業になってきた、、、!
基本情報の勉強になってるのか疑問ですね。
こればっかりやっていても基本情報の勉強効果は薄れ気味だし、
pythonの習得にも偏りがありそうなので、
他にもやること考えます。

pythonの文法としては、
毎回変数のスコープでつまずきます。
関数の中でグローバルな変数を書き換えたいときに
'global 変数'のコードを忘れていて、
「UnboundLocalError: local variable 'DataLen' referenced before assignment」
みたいなことをpython先輩に言われてしまう。
にしても関数を書くときに毎回、global って定義するの面倒だなーと思います。
関数の中からグローバル変数を書き換えたい場合の、もっといい方法ないのかしら。
知ってるよって先生方いらっしゃいましたら教えてください。


以上です。
それではまた^^