This is the swift code I have as an exercise from my class, I am re-writing it(as I am new to it).
At the position of
let end = starIndex.advancedBy(position), I am getting an error message of String.Index does not have a member named advancedBy I am not sure what this means or how to correct it just yet, many thanks for any help in understanding what I am doing wrong.
//: Playground - noun: a place where people can play
import UIKit
var str : String = "Hello, playground"
str
let strFix = " Can not change"
str = "Good bye"
//strFix = "Testing"
var str2 = str + "F"
var townName = "NeverLand"
let population = 30000
let numOfStopLight : Int = 10
print("\(townName) has populations of \(population)
and has \ (numOfStopLight) Stop Lights")
for c in townName.unicodeScalars
{
print ("\(c)")
}
let starIndex = str.startIndex
let position = 3
let end = starIndex.advancedBy(position)
let charAt = str[end]
let range = starIndex...end
str[range]
let aChar: Character = "\u{1F60E}"
str.append(aChar)
let dollarSign = "\u{24}" //$, Unicode scalar U+0024
let blackHeart = "\u{2665}" // , Unicode scalar U+2665
let sparklingHeart = "\u{1F496}" // , Unicod scalar U=1F496
str.append(Character(sparklingHeart))
for c in str.characters
{
print("\(c)")
}
for c in str.unicodeScalars
{
print("\(c.value)")
}
/////////////////////
struct Car
{
var make : String = ""
var price : Double = 0.0
let color : String = "RED"
func getMske()->String
{
return make
}
mutating func setMake (m: String)
{
make = m
}
func showCar()->String
{
return "Make:\(make) Price=\(price) Color= \(color)"
}
}
//let us make some Car
var myCar = Car(make: "Nissan", price: 45000.0)
print(myCar.showCar())
myCar.setMake("Nissan2016")
print (myCar.showCar())
//show pass value
func doChange (var c: Car)
{
c.setMake("Toyota")
print (c.showCar())
}
doChange(myCar)
print (myCar.showCar())
//let us have a class
class Xcar
{
var make :String = ""
var price : Double = 0.0
var color : String = ""
init(m :String, p: Double, c: String)
{
self.make = m
self.price = p
self.color = c
}
func setMake(m: String)
{
self.make = m
}
func showXCar()->String
{
return "Make: \(make) Price=\(price) Color=\(color)"
}
}
func doChangex( c:Xcar)
{
c.setMake("BMW")
print("\(c.showXCar())")
}
var hisCar = Xcar(m: "Fiat", p: 15000.0, c: "Blue")
print ("\(hisCar.showXCar())")
doChangex(hisCar)
//notice the function did change
//because it was a class
print ("\(hisCar.showXCar())")
//What is optional
let a: Float?
let b: Float?
let c :Float?
a = 10
b = 20
c = 5
//this is implicit unrap
let ave = (a! + b! + c!)/3.0
if let x = a, y = b, z = c
{
print ("\((x + y + z) / 3.0)")
}
else
{
print ("missing value...")
}
// note Array, Double, Float, Int and Dictionary are all struct
var intArray = [Int] ()
intArray.append(50)
intArray.append(100)
intArray.append(600)
intArray.maxElement()
intArray.capacity
intArray.count
intArray.description
intArray.dropFirst()
intArray.first
intArray.description
intArray.removeFirst()
intArray.description
for c in intArray
{
print("\(c)")
}
var dict = [Int :String ] ()
dict = [235 :"Jack", 100: "Joe", 60: "Lisa"]
dict.description
for(key, value) in dict
{
print ("\(key)")
}
var name = dict[235]
Try doing it in one line
let startIndex = str.startIndex.advancedBy(3)
The code has a number of issues and we don't know what the expected output is, but here are a few items:
The line with just 'str' on it should be removed.
You may be running an older version of Xcode or OS (or both). This is Swift2 and you should be using Xcode 7 or higher.
Also, there are 'var' that should be 'let' (hisCar) and there are a number of unused variables.
The good news is once you fix the issues that, the code runs correctly (as far as I can tell)
Related
Given a string of arbitrary length. I need to find 1 subsequences of identical characters that go in a row.
My function (there are two of them, but these are two parts of the same function) turned out to be complex and cumbersome and did not fit because of this. The function I need should be simple and not too long.
Example:
Input : str = "abcabc"
Output : abc
Input : str = "aa"
Output : a
Input : str = "abcbabcb"
Output : abcb
Input : str = "abcbca"
Output : bcbc
Input : str = "cbabc"
Output :
Input : str = "acbabc"
Output :
My unsuccessful function:
func findRepetition(_ p: String) -> [String:Int] {
var repDict: [String:Int] = [:]
var p = p
while p.count != 0 {
for i in 0...p.count-1 {
repDict[String(Array(p)[0..<i]), default: 0] += 1
}
p = String(p.dropFirst())
}
return repDict
}
var correctWords = [String]()
var wrongWords = [String]()
func getRepeats(_ p: String) -> Bool {
let p = p
var a = findRepetition(p)
for i in a {
var substring = String(Array(repeating: i.key, count: 2).joined())
if p.contains(substring) {
wrongWords.append(p)
return false
}
}
correctWords.append(p)
return true
}
I will be very grateful for your help!
Here's a solution using regular expression. I used a capture group that tries to match as many characters as possible such that the whole group repeats at least once.
import Foundation
func findRepetition(_ s: String) -> String? {
if s.isEmpty { return nil }
let pattern = "([a-z]+)\\1+"
let regex = try? NSRegularExpression(pattern: pattern, options: [])
if let match = regex?.firstMatch(in: s, options: [], range:
NSRange(location: 0, length: s.utf16.count)) {
let unitRange = match.range(at: 1)
return (s as NSString).substring(with: unitRange)
}
return nil
}
print(findRepetition("abcabc")) //prints abc
print(findRepetition("aa")) //prints a
print(findRepetition("abcbabcb")) //prints abcb
print(findRepetition("abcbca")) //prints bc
print(findRepetition("cbabc")) //prints nil
print(findRepetition("acbabc")) //prints nil
func findRepetitions(_ p : String) -> [String: Int]{
let half = p.count / 2 + 1
var result : [String : Int] = [:]
for i in 1..<half {
for j in 0...(p.count-i) {
let sub = (p as! NSString).substring(with: NSRange.init(location: j, length: i))
if let val = result[sub] {
result[sub] = val + 1
}else {
result[sub] = 1
}
}
}
return result
}
This is for finding repetitions of possible substrings in your string. Hope it can help
Here is a solution that is based on the Suffix Array Algorithm, that finds the longest substring that is repeated (contiguously):
func longestRepeatedSubstring(_ str: String) -> String {
let sortedSuffixIndices = str.indices.sorted { str[$0...] < str[$1...] }
let lcsArray = [0]
+
sortedSuffixIndices.indices.dropFirst().map { index in
let suffix1 = str[sortedSuffixIndices[index]...]
let suffix2 = str[sortedSuffixIndices[index - 1]...]
let commonPrefix = suffix1.commonPrefix(with: suffix2)
let count = commonPrefix.count
let repeated = suffix1.dropFirst(count).commonPrefix(with: commonPrefix)
return count == repeated.count ? count : 0
}
let maxRepeated = zip(sortedSuffixIndices.indices,lcsArray).max(by: { $0.1 < $1.1 })
if let tuple = maxRepeated, tuple.1 != 0 {
let suffix1 = str[sortedSuffixIndices[tuple.0 - 1]...]
let suffix2 = str[sortedSuffixIndices[tuple.0]...]
let longestRepeatedSubstring = suffix1.commonPrefix(with: suffix2)
return longestRepeatedSubstring
} else {
return ""
}
}
Here is an easy to understand tutorial about such an algorithm.
It works for these examples:
longestRepeatedSubstring("abcabc") //"abc"
longestRepeatedSubstring("aa") //"a"
longestRepeatedSubstring("abcbabcb") //"abcd"
longestRepeatedSubstring("abcbca") //"bcbc"
longestRepeatedSubstring("cbabc") //""
longestRepeatedSubstring("acbabc") //""
As well as these:
longestRepeatedSubstring("a😍ca😍c") //"a😍c"
longestRepeatedSubstring("Ab cdAb cd") //"Ab cd"
longestRepeatedSubstring("aabcbc") //"bc"
Benchmarks
Here is a benchmark that clearly shows that the Suffix Array algorithm is much faster than using a regular expression.
The result is:
Regular expression: 7.2 ms
Suffix Array : 0.1 ms
I want to iterate over an array String?, String repeated pair but I cannot form the "for case let (a,b) in array" correctly.
The best I have come up with is to create a temp struct of {String?, String} and create an array of the temp structs and then iterate it but I would like to skip this step.
Below is the basic example with the last for loop showing the error Xcode reports.
class Foo {
var s1: String?
var s2: String?
var s3: String?
}
let foo = Foo()
foo.s1="Test1"
foo.s2=nil
foo.s3="Test3"
let fooArray = [foo.s1, ", ", foo.s2, "; ", foo.s3,"."]
let fooArray1 = [foo.s1,foo.s2, foo.s3]
var text:String = ""
for case let prop? in fooArray1 {
text = text + prop + " / "
}
print(text)
// The above works but now I want to use a different separator
//base on the property name
text=""
for case let (prop, sep) in fooArray { // Error <= Expression Type
// [String?] is ambiguous without more context
text = text + prop + sep
}
print(text)
Here is what I have come up with
struct temp {
var prop:String?
var sep:String
init(_ prop:String?, _ sep:String) {
self.prop=prop
self.sep=sep
}
let ary:[temp] = [ temp(foo.s1,", "), temp(foo.s2,"; "), temp(foo.s3,".") ]
text = ""
for a in ary {
if let p = a.prop {
text = text + p + a.sep
}
}
print (text)
is there another way just using the for loop
for (a,b) in fooArray {
...
}
As noted by #RJE, the inferred type of fooArray, as defined in your code, is [String?].
Here is one way to make it work:
class Foo {
var s1: String?
var s2: String?
var s3: String?
}
let foo = Foo()
foo.s1 = "Test1"
foo.s2 = nil
foo.s3 = "Test3"
let fooArray1 = [foo.s1, foo.s2, foo.s3]
let separators = [", ", "; ", "."]
var text = ""
for i in fooArray1.indices {
if let p = fooArray1[i] {
text = text + p + separators[i]
}
}
print (text) //Test1, Test3.
Or
let zipped = zip(fooArray1, separators)
let text = zipped.map { tuple -> String in
if case let (x?, y) = tuple {
return x + y
} else {
return ""
}
}.joined()
print (text) //Test1,Test3.
Or
let fooArray = [foo.s1, ", ", foo.s2, "; ", foo.s3, "."]
var text = ""
var step = 1
var index = 0
while index < fooArray.count {
if let str = fooArray[index] {
step = 1
text += str
} else {
step = 2
}
index += step
}
print(text) //Test1, Test3.
It would be better to define the initializer this way :
class Foo {
var s1: String?
var s2: String?
var s3: String?
init(s1: String?, s2: String?, s3: String?) {
self.s1 = s1
self.s2 = s2
self.s3 = s3
}
}
let foo = Foo(s1: "Test1", s2: nil, s3: "Test3")
P.S: The desired output seems to be more appropriate for a description property of the Foo class.
Thanks for the answer I was hoping through this question to get a better understanding of how to use [for] parameters. But the while solution is the solution I would probably use with the following modifications
text = ""
var index = 0
while index < fooArray.count {
if let prop = fooArray[index] {
index += 1
let sep = fooArray[index]!
index += 1
text = text + prop + sep
} else {
index += 2
}
}
I would like to be able to find and replace occurrences of a substring in a native Swift string without bridging to the NS class. How can I accomplish this?
This is not a duplicate of this question, as that question is about replacing a single character. This question is about finding and replacing a substring, which may contain many characters.
Method without Foundation:
extension String {
func replacing(_ oldString: String, with newString: String) -> String {
guard !oldString.isEmpty, !newString.isEmpty else { return self }
let charArray = Array(self.characters)
let oldCharArray = Array(oldString.characters)
let newCharArray = Array(newString.characters)
var matchedChars = 0
var resultCharArray = [Character]()
for char in charArray {
if char == oldCharArray[matchedChars] {
matchedChars += 1
if matchedChars == oldCharArray.count {
resultCharArray.append(contentsOf: newCharArray)
matchedChars = 0
}
} else {
for i in 0 ..< matchedChars {
resultCharArray.append(oldCharArray[i])
}
if char == oldCharArray[0] {
matchedChars = 1
} else {
matchedChars = 0
resultCharArray.append(char)
}
}
}
return String(resultCharArray)
}
}
Example usage:
let myString = "Hello World HelHelloello Hello HellHellooo"
print(myString.replacing("Hello", with: "Hi"))
Output:
Hi World HelHiello Hi HellHioo
Method using Foundation:
You can use the replacingOccurrences method on the String struct.
let myString = "Hello World"
let newString = myString.replacingOccurrences(of: "World", with: "Everyone")
print(newString) // prints "Hello Everyone"
generic and pure Swift approach
func splitBy<T: RangeReplaceableCollection>(_ s:T, by:T)->[T] where T.Iterator.Element:Equatable {
var tmp = T()
var res = [T]()
var i:T.IndexDistance = 0
let count = by.count
var pc:T.Iterator.Element {
get {
i %= count
let idx = by.index(by.startIndex, offsetBy: i)
return by[idx]
}
}
for sc in s {
if sc != pc {
i = 0
if sc != pc {
} else {
i = i.advanced(by: 1)
}
} else {
i = i.advanced(by: 1)
}
tmp.append(sc)
if i == count {
tmp.removeSubrange(tmp.index(tmp.endIndex, offsetBy: -i)..<tmp.endIndex)
res.append(tmp)
tmp.removeAll()
}
}
res.append(tmp)
return res
}
func split(_ s:String, by:String)->[String] {
return splitBy(s.characters, by: by.characters).map(String.init)
}
extension RangeReplaceableCollection where Self.Iterator.Element: Equatable {
func split(by : Self)->[Self] {
return splitBy(self, by: by)
}
}
how to use it?
let str = "simple text where i would like to replace something with anything"
let pat = "something"
let rep = "anything"
let s0 = str.characters.split(by: pat.characters).map(String.init)
let res = s0.joined(separator: rep)
print(res) // simple text where i would like to replace anything with anything
let res2 = split(str, by: pat).joined(separator: rep)
print(res2) // simple text where i would like to replace anything with anything
let arr = [1,2,3,4,1,2,3,4,1,2,3]
let p = [4,1]
print(arr.split(by: p)) // [[1, 2, 3], [2, 3], [2, 3]]
Pardon me as I am a newbie on this language.
Edit: Is there a way to reverse the position of a array element?
I am trying to create a function that test the given input if its a palindrome or not. I'm trying to avoid using functions using reversed()
let word = ["T","E","S","T"]
var temp = [String]()
let index_count = 3
for words in word{
var text:String = words
print(text)
temp.insert(text, atIndex:index_count)
index_count = index_count - 1
}
Your approach can be used to reverse an array. But you have to
insert each element of the original array at the start position
of the destination array (moving the other elements to the end):
// Swift 2.2:
let word = ["T", "E", "S", "T"]
var reversed = [String]()
for char in word {
reversed.insert(char, atIndex: 0)
}
print(reversed) // ["T", "S", "E", "T"]
// Swift 3:
let word = ["T", "E", "S", "T"]
var reversed = [String]()
for char in word {
reversed.insert(char, at: 0)
}
print(reversed) // ["T", "S", "E", "T"]
The same can be done on the characters of a string directly:
// Swift 2.2:
let word = "TEST"
var reversed = ""
for char in word.characters {
reversed.insert(char, atIndex: reversed.startIndex)
}
print(reversed) // "TSET"
// Swift 3:
let word = "TEST"
var reversed = ""
for char in word.characters {
reversed.insert(char, at: reversed.startIndex)
}
print(reversed)
Swift 5
extension String {
func invert() -> String {
var word = [Character]()
for char in self {
word.insert(char, at: 0)
}
return String(word)
}
}
var anadrome = "god"
anadrome.invert()
// "dog"
Here's my solution:
extension String {
func customReverse() -> String {
var chars = Array(self)
let count = chars.count
for i in 0 ..< count/2 {
chars.swapAt(i, count - 1 - i)
}
return String(chars)
}
}
let input = "abcdef"
let output = input.customReverse()
print(output)
You can try it here.
func reverse(_ str: String) -> String {
let arr = Array(str) // turn the string into an array of all of the letters
let reversed = ""
for char in arr {
reversed.insert(char, at: reversed.startIndex)
}
return reversed
}
To use it:
let word = "hola"
let wordReversed = reverse(word)
print(wordReversed) // prints aloh
Another solution for reversing:
var original : String = "Test"
var reversed : String = ""
var c = original.characters
for _ in 0..<c.count{
reversed.append(c.popLast()!)
}
It simply appends each element of the old string that is popped, starting at the last element and working towards the first
Solution 1
let word = "aabbaa"
let chars = word.characters
let half = chars.count / 2
let leftSide = Array(chars)[0..<half]
let rightSide = Array(chars.reverse())[0..<half]
let palindrome = leftSide == rightSide
Solution 2
var palindrome = true
let chars = Array(word.characters)
for i in 0 ..< (chars.count / 2) {
if chars[i] != chars[chars.count - 1 - i] {
palindrome = false
break
}
}
print(palindrome)
static func reverseString(str : String) {
var data = Array(str)
var i = 0// initial
var j = data.count // final
//either j or i for while , data.count/2 buz only half we need check
while j != data.count/2 {
print("befor i:\(i) j:\(j)" )
j = j-1
data.swapAt(i, j) // swapAt API avalible only for array in swift
i = i+1
}
print(String(data))
}
//Reverse String
let str = "Hello World"
var reverseStr = ""
for char in Array(str) {
print(char)
reverseStr.insert(char, at: str.startIndex)
}
print(reverseStr)
I ran the same code in Xcode 7beta/rc Playground project and got an error:
Execution was interrupted, reason: EXC_BAD_ACCESS(code=EXC_I386_GPFLT)
in
let n: Int = Int(Process.arguments[1])!
How do I solve in Playground project since other solutions don't seem to be related?
Binary tree: http://benchmarksgame.alioth.debian.org/u64q/program.php?test=binarytrees&lang=swift&id=1
class TreeNode {
var left, right : TreeNode?
var item : Int
init(_ left: TreeNode?, _ right: TreeNode?, _ item: Int) {
self.left = left
self.right = right
self.item = item
}
func check() -> Int {
guard let left = left, let right = right else {
return item
}
return item + left.check() - right.check()
}
}
func bottomUpTree(item: Int, _ depth: Int) -> TreeNode {
if depth > 0 {
return
TreeNode(
bottomUpTree(2*item-1, depth-1),
bottomUpTree(2*item, depth-1),
item
)
}
else {
return
TreeNode(nil,nil,item)
}
}
let n: Int = Int(Process.arguments[1])!
let minDepth = 4
let maxDepth = n
let stretchDepth = n + 1
let check = bottomUpTree(0,stretchDepth).check()
print("stretch tree of depth \(stretchDepth)\t check: \(check)")
let longLivedTree = bottomUpTree(0,maxDepth)
var depth = minDepth
while depth <= maxDepth {
let iterations = 1 << (maxDepth - depth + minDepth)
var check = 0
for i in 0..<iterations {
check += bottomUpTree(i,depth).check()
check += bottomUpTree(-i,depth).check()
}
print("\(iterations*2)\t trees of depth \(depth)\t check: \(check)")
depth += 2
}
print("long lived tree of depth \(maxDepth)\t check: \(longLivedTree.check())")
Process.arguments holds the value that is passed as arguments for a command-line application.
But you're using it in a Playground: there's no access to command line input from a Playground (they are Sandboxed), so Process.arguments is nil and your app crashes when you're doing Process.arguments[1].
The solution is to use this in an actual application, not in a Playground.
You can use a custom "readLine()" function and a global input variable, each element in the input array is presenting a line:
import Foundation
var currentLine = 0
let input = ["5", "5 6 3"]
func readLine() -> String? {
if currentLine < input.endIndex {
let line = input[currentLine]
currentLine += 1
return line
} else {
return nil
}
}
let firstLine = readLine() // 5
let secondLine = readLine() // 5 6 3
let thirdLine = readLine() // nil