问题是反转字符串的元音,就像输入“hello”一样,输出应该是“holle”。
我在swift中搜索没有这样的问题,所以我想把它作为讨论发布。
我编写了如下代码,事实证明需要12毫秒来反转这个“你好”,任何人都可以通过使用swift功能获得更好的解决方案吗?
class Solution {
func reverseVowels(s: String) -> String {
if s == "" { return "" }
let vowels = ["a","e","i","o","u","A","E","I","O","U"]
var sVowels = [Character]()
var reversedStr = ""
for vChar in s.characters {
if vowels.contains(String(vChar)) {
sVowels.append(vChar)
}
}
for char in s.characters {
if !vowels.contains(String(char)) {
reversedStr = reversedStr + String(char)
} else if vowels.contains(String(char)) {
reversedStr = reversedStr + String(sVowels.removeLast())
}
}
return reversedStr
}
}
答案 0 :(得分:4)
添加到vacawama's answer解决方案:
与其他流行语言(即C#和Java)不同,Swift并不要求所有函数都在类中。 Solution
是一个相当随意的类,不需要存在。在Swift中,您可以将您的函数编写为自己的独立实体。
然而,有一个更好的快速方法。您可以将函数放入String
的扩展中,这会产生一些非常好的语法:
extension String {
static let vowels: Set<Character> = ["a","e","i","o","u","A","E","I","O","U"]
func reverseVowels() -> String {
if self == "" { return "" }
var chars = Array(self.characters)
let indices = chars.enumerate().filter{ String.vowels.contains($0.1) }.map{ $0.0 }
let count = indices.count
for i in 0 ..< count/2 {
swap(&chars[indices[i]], &chars[indices[count - i - 1]])
}
return String(chars)
}
}
"A test string".reverseVowels() //you can call your method directly on a string
我在答案上做了其他改进:
vowels
移动为String
类的静态成员,以便在reverseVowels()
的每次调用时都不会重新生成它(尽管编译器可能会将其优化为这一点)。vowels
现在是Set
,而不是Array
,以便使用其contains()
的更快版本。通过我的测试,这使得 1.4x 的功能更快。indices
数组。答案 1 :(得分:3)
您的问题更多的是算法问题,而不是Swift问题。我对Swift一无所知。
所以这是我用Java编写的算法解决方案。以下是您可以在代码中使用的要点:
import java.util.Set;
import java.util.HashSet;
import java.util.Arrays;
public class ReverseVowels {
public static String reverseVowels(String s) {
// Create a hash table for vowels.
Set<Character> vowels =
new HashSet<Character>(
Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));
// Convert input string to array so that we can write into it.
char[] result = s.toCharArray();
int i = 0;
int j = result.length-1;
while (i < j) {
if (!vowels.contains(result[i])) {
i++;
}
else if (!vowels.contains(result[j])) {
j--;
}
else {
// Both are vowels.
char temp = result[i];
result[i] = result[j];
result[j] = temp;
i++;
j--;
}
}
return new String(result);
}
public static void main(String argv[]) {
System.out.printf("%s\n", reverseVowels("hello"));
System.out.printf("%s\n", reverseVowels("qwetupoabt"));
}
}
输出:
% java ReverseVowels
holle
qwatopuebt
迅速翻译:
func reverseVowels(s: String) -> String {
// Create a set for vowels.
let vowels: Set<Character> = ["a","e","i","o","u","A","E","I","O","U"]
// Convert input string to array so that we can write into it.
var result = Array(s.characters)
var i = 0
var j = result.count - 1
while i < j {
if !vowels.contains(result[i]) {
i += 1
}
else if !vowels.contains(result[j]) {
j -= 1
}
else {
// Both are vowels.
let temp = result[i]
result[i] = result[j]
result[j] = temp
i += 1
j -= 1
}
}
return String(result)
}
答案 2 :(得分:3)
试试这个:
func reverseVowels(s: String) -> String {
if s == "" { return "" }
let vowels: Set<Character> = ["a","e","i","o","u","A","E","I","O","U"]
var indices = [Int]()
var chars = Array(s.characters)
for (index, vChar) in chars.enumerate() {
if vowels.contains(vChar) {
indices.append(index)
}
}
let count = indices.count
for i in 0 ..< count/2 {
swap(&chars[indices[i]], &chars[indices[count - i - 1]])
}
return String(chars)
}
算法:
vowels
成为Set<Character>
以减少转化次数并加快contains
(感谢@AlexMomchliov提出Set
提示)[Character]
[Character]
答案 3 :(得分:1)
另一种方式:
1拿起所有元音,并将它们反转。
2使用反向元音映射原始字符串中的所有元音。
func reverseVowels(s: String) -> String {
let vowelSet: Set<Character> = ["a","e","i","o","u","A","E","I","O","U"]
var reversedVowelIterator = s.characters.filter{vowelSet.contains($0)}.lazy.reverse().generate()
return String(s.characters.map{vowelSet.contains($0) ? reversedVowelIterator.next()! : $0})
}
print(reverseVowels("hello")) //->holle
print(reverseVowels("Reverse Vowels of a String")) //->Rivarso Vewols ef e Streng