2016-10-31 23 views
0

我目前正在一个小型应用程序进行化学计算。我试图编程一个分子计算器,你只需输入总和公式和它的数量。没有任何数字,它可以完美地工作,例如,如果我输入NaCl的数量为100克(在不同的文本字段中输入克数),您将得到约1.73 mol,这是正确的解决方案。检查并得到只有诠释出一串字符串

我现在想要做的是我可以添加数字,例如Na2Cl4。在我的方法中,字符串被正确分割,如果你打印它,你会得到["Na", "2", "Cl", "4"],但我不知道我怎么能得到Int的出来,并记住它们被分配给哪个元素(2到Na和4到Cl,因为我需要将mol/g乘以2)。

我试过以下内容: 该数字将始终在奇数索引上(Na在0,2在1,Cl在2,4在3),所以我试图把每个元素都放在一个奇数索引中新阵列:

var i = 0 
    var testarray = [String]() 

    for content in splitted { 
     if i % 2 == 0 { 

     }else { 
     testarray.append(content) 
     } 
     print(content) 
     i += 1 
    } 

splitted是包含拆分和公式的[String]数组。我得到的结果如果我打印出内容是2和4这是很好,但如果我输入例如Na10我得到1和0这是不好,也不知道它分配给哪个元素。

有没有人知道如何解决这个问题,我可以从字符串数组中获取Int值,并记住它们分配给哪个元素?

在此先感谢!

编辑:

继承人的代码我如何分割字符串:

let splitted = summenformel.characters.splitBefore(separator: { $0.isUpperCase }).map{String($0)} 

和扩展:

extension Sequence { 
    func splitBefore(
     separator isSeparator: (Iterator.Element) throws -> Bool 
     ) rethrows -> [AnySequence<Iterator.Element>] { 
     var result: [AnySequence<Iterator.Element>] = [] 
     var subSequence: [Iterator.Element] = [] 

     var iterator = self.makeIterator() 
     while let element = iterator.next() { 
      if try isSeparator(element) { 
       if !subSequence.isEmpty { 
        result.append(AnySequence(subSequence)) 
       } 
       subSequence = [element] 
      } 
      else { 
       subSequence.append(element) 
      } 
     } 
     result.append(AnySequence(subSequence)) 
     return result 
    } 
} 

extension Character { 
    var isUpperCase: Bool { return String(self) == String(self).uppercased() } 
} 
+0

你能告诉我你是如何创建分裂 – Knight0fDragon

+0

考虑使用例如'[A-Z]([A-Z] +)正则表达式?(\\ d +)?',因为一个元素以大写字母总是启动。 – vadian

+0

@ Knight0fDragon这个班很大,去看看我的github吧! [链接](https://github.com/andinator/ProChemistry/blob/master/ProChemistry/CalculatorBrain.swift) – Andi

回答

1

用正则表达式替代做法

正则表达式搜索:

一个大写字母后跟可选的小写字母后跟可选的数字

let string = "Na10Cl4" 

let pattern = "([A-Z]([a-z]+)?)(\\d+)?" 
let regex = try! NSRegularExpression(pattern: pattern, options: []) 
let matches = regex.matches(in: string, options: [], range: NSRange(location: 0, length: string.characters.count)) 
for match in matches { 
    let elementRange = match.rangeAt(1) // capture group of the element 
    let element = (string as NSString).substring(with: elementRange) 
    print("element", element) 
    let quantityRange = match.rangeAt(3) // capture group of the quantity 
    let quantity : Int 
    if quantityRange.location != NSNotFound { 
    quantity = Int((string as NSString).substring(with: quantityRange))! 
    } else { 
    quantity = 1 
    } 
    print("quantity", quantity) 
} 
+0

我得到的错误是抛出的错误没有处理 – Andi

+1

我的不好,在我试试' – vadian

+0

最好的工作解决方案后添加感叹号!非常感谢你!你真的是我的一天! – Andi

0

,因为它似乎你在这里有几个问题。我会尽力解决所有问题。

分割字符串

var elements: [String]; 
var nums: [Int]; 
let input: String = "Na2Cl4" 
for (index,char) in input.characters.enumerate() { 
    if char.lowercaseString != char { //Is uppercase letter 
     elements.append(char + input[index + 1]) //Add the element "Na" to the elements array. 
    }else if Int(char) != nil { 
     var tempInt = char 
     if input[index + 1] != nil { 
      tempInt += input[index + 1] 
     } 
     nums.append(tempInt) //Add the integer 4 to the array. 
    } 
} 

所以这会给你["Na","Cl"][2,4]到阵列。如果你输入Na10Cl25,你也有同样的elements阵列nums[10,25]

的数学

现在有两个单独的数组,你可以很容易地知道哪些Int属于哪个元素。

for (index,value) in elements.enumerate(){ 
    let thisElementValue = (mol/g) * nums[index] 
    print("There are \(nums[index]) \(value) molecules") 
} 
+0

@RajanMaheshwari正好。 – Andi

+0

好的,那么你如何将元素和分子值存储在单独的数组中。这样,当你引用'element [0]'和'mol [0]'时,你将拥有不同的值,但是你也会知道它属于哪个元素。你没有表现出你的分裂。 – TheValyreanGroup

+0

我会肯定地尝试,但正如我所说,即时通讯非常新,所以它可能需要一段时间,直到我使它与我的代码“兼容”,因为atm我把每个找到的元素放入一个新的数组中,并将它与以mol/g为例存储的字典[“Na”:23,“Cl”:35] – Andi

相关问题