🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

853閲覧

n 個の文字と数字の組をreadLine()で読み込み?同じ文字同士で数字の計算

anmoanmo

総合スコア2

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/02/02 12:47

プログラミング 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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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}

あるいは、こういう書き方もできるかと思います。

こちらは、Dictionaryreduce を使っています。

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

TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

anmoanmo

2021/02/02 16:51

初回の登録時に値を代入といった発想ができませんでした。 大変勉強になりました。 ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問