好的,所以我當前的代碼可以作業,但我感覺它的效率非常低。本質上,我需要評估一個 String 是否包含一個 String 的字母,該字母的長度是否與第一個字母相同或更短。(想象一下,嘗試使用單詞 A 中存在的字母來拼寫一個新單詞單詞 B。單詞 B 可以比單詞 A 短或相同的長度,但必須只使用單詞 A 中的字母,并且不能使用相同的字母兩次。 )
我目前的解決方案是將兩個字串排序到一個陣列中,然后索引 Word B 陣列中的每個字母,檢查它是否出現在 Word A 陣列中,然后從 Word A 陣列中洗掉該字符。
let wordOne = "battle"
let wordTwo = "table"
var wordOneSorted = wordOne.sorted()
var wordTwoSorted = wordTwo.sorted()
for letter in wordTwoSorted {
if wordOneSorted.contains(letter) {
print("Valid Letter")
let idx = wordOneSorted.firstIndex(of:letter)
wordOneSorted.remove(at: idx!)
} else {
print("Invalid Letter")
}
}
列印: 有效信函 有效信函 有效信函 有效信函 有效信函
這行得通,但感覺很笨拙,我想看看我是否讓一個簡單的任務變得比我需要的更復雜。我只需要對整個比較進行評估,如果所有字母都比“True”有效,并且至少有一個無效而不是“False”。
謝謝!
uj5u.com熱心網友回復:
您的代碼可以給出簡單的好/壞回應,如下所示:
let wordOne = "battle"
let wordTwo = "table"
var letters = wordOne
var good = true
for letter in wordTwo {
if letters.contains(letter) {
let idx = letters.firstIndex(of:letter)
letters.remove(at: idx!)
} else {
good = false
break
}
}
print(good ? "Good" : "Bad")
無需對每個單詞的字母進行排序。這并沒有使這種方法更有效。我添加了var lettersjust 以便可以在回圈運行時修改值。
這是使用NSCountedSet. 這不是一個純Swift類,而是由 Foundation 提供的。
let wordOne = "battle"
let wordTwo = "table"
let set1 = NSCountedSet(array: Array(wordOne))
let set2 = NSCountedSet(array: Array(wordTwo))
let extra = set2.filter { set2.count(for: $0) > set1.count(for: $0) }
print(extra.isEmpty ? "Good" : "Bad")
NSCountedSet是Set(實際上是NSSet和NSMutableSet)的子類,它為集合中的每個元素添加一個計數。
確保每個filter字母都足夠。extrameans中留下的任何東西wordTwo都比wordOne.
uj5u.com熱心網友回復:
我想知道我會怎么做,這是另一種選擇。對一個問題有不同的思考方式是件好事。
我們創建一個[Character: (Int, Int)]where - 鍵是字母,第一個元組值是 str1 中出現的次數,第二個元組值是 str2 中出現的次數。
然后,我們檢查 str1 中出現的所有值是否至少與 str2 中出現的次數相同。
var counter: [Character: (Int, Int)] = [:]
counter = str1.reduce(counter) {
var values = $0
var tuple: (Int, Int) = $0[$1, default: (0, 0)]
values[$1] = (tuple.0 1, tuple.1)
return values
}
counter = str2.reduce(counter) {
var values = $0
var tuple: (Int, Int) = $0[$1, default: (0, 0)]
values[$1] = (tuple.0, tuple.1 1)
return values
}
let doesInclude = counter.allSatisfy { _, tuple in
tuple.0 >= tuple.1
}
print("\(str1) includes all letters from \(str2): \(doesInclude)")
"abc"vs的計數器值"cde":
["d": (0, 1), "b": (1, 0), "c": (1, 1), "e": (0, 1), "a": (1, 0)]
"battle"vs的計數器值"table":
["t": (2, 1), "e": (1, 1), "a": (1, 1), "b": (1, 1), "l": (1, 1)]
uj5u.com熱心網友回復:
我喜歡@HangarRash 的回答,但你也可以使用 sort 來發揮你的優勢,即當字母被排序時,你可以同時在兩個陣列中移動并在發現第一個差異時立即停止(不需要洗掉任何東西):
func isContained(in word1: String, word word2: String) -> Bool {
var word1Sorted = word1.sorted()
var word2Sorted = word2.sorted()
var c1 = word1Sorted.count - 1
var c2 = word2Sorted.count - 1
while c2 >= 0 && c1 >= 0 {
if word1Sorted[c1] == word2Sorted[c2] {
// Found a match - advance to next character in both arrays
print("Valid Letter \(word2Sorted[c2])")
c1 -= 1
c2 -= 1
} else if word1Sorted[c1] > word2Sorted[c2] {
// Ignoring a letter present in wordOne, but not wordTwo
print("Skipping Letter \(word1Sorted[c1])")
c1 -= 1
} else { // wordOneSorted[c1] < wordTwoSorted[c2]
// the letter was not found in wordOneSorted - no need to continue
print("Invalid Letter \(word2Sorted[c2])")
return false
}
}
// If we finished the loop then the result is:
// - We've got to the beginning of word2, meaning we found all letters of it in word1
// - Or we've got to the beginning of word1, meaning not all letters of word 2 were found
return c2 < 0
}
例如:
let wordOne = "battle"
let wordTwo = "table"
let good = isContained(in: wordOne, word: wordTwo)
print(good ? "Good" : "Bad")
將在整個陣列(至少是 Word 2)上運行:
Valid Letter t
Skipping Letter t
Valid Letter l
Valid Letter e
Valid Letter b
Valid Letter a
Good
而如果有差異,例如
let wordOne = "battle"
let wordTwo = "tables"
let good = isContained(in: wordOne, word: wordTwo)
print(good ? "Good" : "Bad")
它可能會退出得更快:
Valid Letter t
Skipping Letter t
Invalid Letter s
Bad
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/535323.html
標籤:数组迅速比较包含
上一篇:Numpy檢查二維numpy陣列的每一行的所有元素是否相同
下一篇:可變長度陣列元素隨機生成器
