プログラミング Swift 初心者
ある問題に挑戦していてどうしても分からない問題があります。
問題
n 個の文字と数字の組をreadLine()で読み込み?同じ文字同士で数字の計算(加算)をします。そして、最後に昇順で出力します。
入力例
5
A 1
D 6
A 2
G 4
B 70
出力例
B 70
D 6
G 4
A 3
この形で出力したいです。入力も出力もpaizaというサイトのエディターで行います。
辞書型で格納して、同じ文字同士で加算みたいなことができたらと思いましたが、辞書型はkeyの重複はダメですし、配列で格納した場合、最後に出力する時に文字と数字のペアを崩さずに出力する方法が思いつきませんでした。
自分で調べることが大事だとは思いましたが、どうか教えていただきたいです。
ご回答よろしくお願いいたします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
ベストアンサー
少しくどく書くならこのような感じになります。
Swift の辞書には、キーとして与えられた値が存在しない場合のデフォルト値を与える方法があるので、それを活用して加算します。
Accesses the value with the given key. If the dictionary doesn’t contain the given key, accesses the provided default value as if the key and default value existed in the dictionary.
defautl:
を知らなくてもオプショナルバインディングなどで nil
判定を使ったりすれば書けなくもないですが、おそらくこちらの方がスマートにかけると思います。
- [https://paiza.io/projects/pq0a6HvtTXC-ouMDG_jfAA
](https://paiza.io/projects/pq0a6HvtTXC-ouMDG_jfAA)
Swift
1import Foundation 2 3// 読み込む行数 4let n = Int(readLine()!)! 5 6// 結果を入れる辞書 7var result: [String: Int] = [:] 8 9// 一行ずつ n 行読み込む 10for _ in 0..<n { 11 // 一行読み込み、空白で区切った配列にする 12 let line = readLine()!.split(separator: " ") 13 // 配列の戦闘要素を出出現文字とする 14 let word = String(line[0]) 15 // 配列の 2 版めの要素をその文字に与えられた数値とする 16 let num = Int(line[1])! 17 18 // 辞書を使って加算する 19 result[word, default: 0] += num 20} 21 22// 辞書の結果をソートし、タプルの配列にする 23let sortedResult = result.sorted(by: { $0.value > $1.value }) 24 25 26// 整形して出力する 27for line in sortedResult { 28 print("(line.key) (line.value)") 29}
あるいは、こういう書き方もできるかと思います。
こちらは、Dictionary
の reduce
を使っています。
Returns the result of combining the elements of the sequence using the given closure.
Swift
1_ = readLine() 2 3Array(AnyIterator { readLine() }) 4 .map { $0.split(separator: " ") 5 .map { String($0) } 6 } 7 .reduce(into: [:]) { result, num in 8 result[num[0], default:0] = Int(num[1])! 9 } 10 .sorted { $0.value > $1.value } 11 .forEach { 12 print($0.key, $0.value) 13 }
ちなみに、最初のコードを default:
を使わずに書くとこのような感じになります。
Swift
1import Foundation 2 3// 読み込む行数 4let n = Int(readLine()!)! 5 6// 結果を入れる辞書 7var result: [String: Int] = [:] 8 9// 一行ずつ n 行読み込む 10for _ in 0..<n { 11 // 一行読み込み、空白で区切った配列にする 12 let line = readLine()!.split(separator: " ") 13 // 配列の戦闘要素を出出現文字とする 14 let word = String(line[0]) 15 // 配列の 2 版めの要素をその文字に与えられた数値とする 16 let num = Int(line[1])! 17 18 if result[word] == nil { 19 // 初回の登録時は値を代入 20 // ここはアンラップしない 21 result[word] = num 22 } else { 23 // 初回以降は値を加算する 24 // こちらはアンラップする 25 result[word]! += num 26 } 27} 28 29// 辞書の結果をソートし、タプルの配列にする 30let sortedResult = result.sorted(by: { $0.value > $1.value }) 31 32 33// 整形して出力する 34for line in sortedResult { 35 print("(line.key) (line.value)") 36}
Dictionary
に値を代入するときにはアンラップせず、一方加算するときにはアンラップするなど、辞書の振る舞いに気をつけなければいけない分、多少ややこしくなります。
投稿2021/02/02 13:36
総合スコア5086
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/02/02 16:51