2019年7月10日水曜日

電卓用の数字のキューをSwiftで作ってみた

Swiftはなかなかいい言語だったので、Swiftを使って電卓を作り直していきたいと思います。

Swiftの特徴としては、まずオプショナルバインディングという方法で、値がnilでなければ実行する、という判定・実行の方法があり、この方法を使うと、エラーを出さずに処理を書くことが簡単にできるという感じで、書いてみるとなかなか便利なことがわかりました。

あと集合(Set)が判定に便利ですね。ここでは0から9の数字かどうかの判定に集合を使っています。

あとは複数の値を返すタプルが地味に関数の記述に便利です。関数をオブジェクトっぽく記述することができあす。



ということで、まずは電卓用に数字を入れるキューを作りたいと思います。

0から9までの文字しか入らないキューを、電卓用として、後ろから入れていき、後ろから抜いていくキュー操作を実装しています。

ただ、これだと小数点が入ってないですね。あと国によっては小数点が","になるのでそれをどうするか忘れています。ちょっと古いコードを見返すかなぁ・・

//
//  ViewController.swift
//  Prototype
//
//  Created by mobazou on 2019/07/09.
//  Copyright © 2019 Taizo Yamamoto. All rights reserved.
//

import UIKit


func changeString2Character(_ inputString:String)->Character?{
    
    if (inputString.count > 1) || (inputString.count == 0) {
        return nil
    }
    else{
        return Character(inputString)
    }
}

//---------------------------
// キュークラス
// Input: CHaracter
// Output: OK:True NG:False
//----------------------------
// init: キューをクリア
//
//----------------------------
class Queue{

    let characterSet:Set<Character> = ["1","2","3","4","5","6","7","8","9","0"]
    var val:String

    init(){
            val = ""
    }
    // 入力キャラクターが所定の文字列かどうか
    func pushedCharChk_OK(_ pushed:Character)->Character?{
        if characterSet.contains(pushed){
            return pushed
        } else {
            return nil
        }
    }
    // push the number
    // Output number + char
    func push(_ pushed:Character)->String?{
        
        if let pushed_ok = pushedCharChk_OK(pushed) {
            val = val + String(pushed_ok)
            return val
        } else {
            return nil
        }
    }
    // pop the number
    // Output (end of number(char), number -char)
    func pop() -> (c:Character? , s:String?){
        if val.count == 1 {
            val = ""
            return (nil, val)
        }
        else if val.count == 0 {
            return (nil, nil)
        }
        else{
            val = String(val[val.index(val.startIndex,offsetBy:0)..<val.index(val.startIndex,offsetBy:val.count - 1)])
            return (Character(String(val.suffix(1))),val)
        }
    }
}

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        // キューの生成と初期化
        let queue = Queue()
        
        // キューへの値入力と表示
        for i in 0...10 {
            //Character変換で問題なければCharacterをキューに追加する
            if let c = changeString2Character(String(i)){
                if let val = queue.push(c){
                    print(val)
                }
                else {
                    print("invailed character for queue")
                }
            }
            else{
                print("invailed string (not char)")
            }
        }
        
        for _ in 0...10{
            let p = queue.pop()
            
            if  let s = p.s{
                print(s)
            }
            else{
                print("no queue")
            }
            
        }

    }

}

実行の結果はこんな感じになります。

0
01
012
0123
01234
012345
0123456
01234567
012345678
0123456789
invailed string (not char)
012345678
01234567
0123456
012345
01234
0123
012
01
0


no queue

キャラクター以外の文字を入れようとすると叱られますし、
キューがないのにキューを取ろうとすると、キューはないよ、と叱られます。

電卓もこの方法だと簡単に記述できそうな気がします。





0 件のコメント: