1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

順列PをSwiftで書いただけの記事 その2

Last updated at Posted at 2023-09-09

はじめに

以前、順列PをSwiftで書いただけの記事を書きました。
順列とは、「1から4の数字が書いた4枚のカードの並べ方はいくつありますか(また、その並べ方は何か)」という問題で出てくるやつです。1, 3, 2, 4 や 2, 4, 3, 1 が順列。

前に書いたこの記事では要素数を指定したら全部を一気に返す仕様でした。例えば要素数が6なら720個返ってきます。

しかし、現在の状態から次のものへ変換する関数も需要があるのではと思い、(すでに存在すると思うが興味があって)作成しました。
次のものってなんだ、ということですが、
[1, 2, 3, 4]の次は[1, 2, 4, 3]
その次は[1, 3, 2, 4]
その次は[1, 3, 4, 2]
となります。
[1, 2, 3, 4]の状態でこの関数を実行すると[1, 2, 4, 3]に変わります。

仕様

124653から125346にするには

1.配列の後ろから見ていって下がったところを見つける

下がったところ(のインデックス)をkeyとする

Permu1.png

2.keyより右をひっくり返す

Permu2-1.png
Permu2-2.png

3.keyより右を順番に見て、keyより大のものを見つける。それをkeyの値と交換する。

Permu3-1.png
Permu3-2.png

4. 完成

Permu4.png

実装

inoutで渡しているので関数内で書き換えます。
次がある場合はtrueを返します。次がない場合はfalseを返します
初めの状態は 1, 2, 3, 4 のような昇順

import Foundation

func nextPermu(_ a: inout [Int]) -> Bool {

    guard a.count >= 2 else {
        return false //nextは存在しない
    }

    let last = a.count - 1
    
    //find key place
    var key = -1
    var right = a[last]
    for i in (0..<last).reversed() {
        if a[i] < right {
            key = i
            break
        }
        right = a[i]
    }
    guard key != -1 else {
        return false
    }
    
    /* 例 123654のとき
     last 5
     key 2
     順番交換範囲 3個
     順番交換インデックス 3から5
     */
    
    //keyより右をひっくり返す
    let turn = last - key //交換範囲
    /* 例
     turn1 交換作業なし
     turn2 交換作業1回
     turn3 交換作業1回(真ん中は必要なし)
     turn4 交換作業2回
     */
    
    for i in 0..<turn / 2 {
        let temp = a[last - i]
        a[last - i] = a[key + 1 + i]
        a[key + 1 + i] = temp
    }
    
    //keyより右で、初めにあるkeyより大きいものをkeyと交換
    for i in 1...last - key {
        if a[key + i] > a[key] {
            let temp = a[key]
            a[key] = a[key + i]
            a[key + i] = temp
            break
        }
    }
    return true
}

var a = [1, 2, 3, 4, 5, 6]

while nextPermu(&a) {
    print(a)
}

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?