Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 快速低电平串lastIndexOf_String_Swift_C Strings - Fatal编程技术网

String 快速低电平串lastIndexOf

String 快速低电平串lastIndexOf,string,swift,c-strings,String,Swift,C Strings,我需要一个尽可能快的lastIndexOf实现。 我发现字符串前进功能非常慢。 我尝试使用c函数strrchr,尝试将字符串复制到NSData并使用指针,但语法不正确。 我的字符串将始终有1个字节的字符,而我正在搜索的字符串“|”也始终是1个字节 任何使用advance的实现都会太慢,但下面是我能找到的最快的示例: func indexOf(target: String, startIndex: Int) -> Int { var startRange = advance(self

我需要一个尽可能快的lastIndexOf实现。 我发现字符串前进功能非常慢。 我尝试使用c函数strrchr,尝试将字符串复制到NSData并使用指针,但语法不正确。 我的字符串将始终有1个字节的字符,而我正在搜索的字符串“|”也始终是1个字节

任何使用advance的实现都会太慢,但下面是我能找到的最快的示例:

func indexOf(target: String, startIndex: Int) -> Int
{
    var startRange = advance(self.startIndex, startIndex)

    var range = self.rangeOfString(target, options: NSStringCompareOptions.LiteralSearch, range: Range<String.Index>(start: startRange, end: self.endIndex))

    if let range = range {
        return distance(self.startIndex, range.startIndex)
    } else {
        return -1
    }
}

func lastIndexOf(target: String) -> Int
{

    var index = -1
    var stepIndex = self.indexOf(target)
    while stepIndex > -1
    {
        index = stepIndex
        if stepIndex + target.length < self.length
        {
            stepIndex = indexOf(target, startIndex: stepIndex + target.length)
        }
        else
        {
            stepIndex = -1
        }
    }
    return index
}
func indexOf(target:String,startIndex:Int)->Int
{
var startRange=前进(self.startIndex,startIndex)
var range=self.rangeOfString(目标,选项:NSStringCompareOptions.LiteralSearch,范围:range(开始:startRange,结束:self.endIndex))
如果let range=range{
返回距离(self.startIndex,range.startIndex)
}否则{
返回-1
}
}
func lastIndexOf(目标:字符串)->Int
{
var指数=-1
var stepIndex=self.indexOf(目标)
而步骤索引>-1
{
索引=步进索引
如果stepIndex+target.length
这是我需要解析的字符串的一个示例。 变量str:String=“4 | 0 | 66 | 5 | 0 | 3259744 | 6352141 | 1 | 3259744 | WSMxt208L54yZ5irtHC3 | Mc02 |埃夫兰,3.0 0~1240 0 0 0 0 0 0 0 012444 4 0 0 0 0 012444 4 4 0 0 012444 7 7 7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 412444 4 4 4 4 4\12444 4 4 4 4 4 4 4 4\\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1| 1212444 4 412444 412444 4 412444 412444 412444 412444 412444 412444 4 412444 4 412444 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 412444 4 412444 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 14 | 0 | 3259744 | 6352141 | 46 | 24 | 0 | 5 | 15 | 0 | 3259744 | 6352141 | 46 | 0 | 66 | 0 | 0 1249744 | 6352141 | 1 | 3259744 | WSMxt208L54yZ5irtHC3 | Mc02 |埃夫兰,北卡罗来纳州| 36.027992 |-79.2212834 | 0 | 4 | 16 | 0 | 3259744 | 6352141 | 46 | 4 |收到:4 | 0 | 66 | 5 1249744 | MC12404;埃夫兰,3.0 0~1240 0 0 0 0 0 0 0 012444 4 0 0 0 0 012444 4 4 0 0 012444 7 7 7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 412444 4 4 4 4 4\12444 4 4 4 4 4 4 4 4\\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1| 1212444 4 412444 412444 4 412444 412444 412444 412444 412444 412444 4 412444 4 412444 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 412444 4 412444 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 14 | 0 | 3259744 | 6352141 | 46 | 24 | 0 | 5 | 15 | 0 | 3259744 | 6352141 | 46 | 0 | 66 | 0 | 0 1249744 | 6352141 | 1 | 3259744 | WSMxt208L54yZ5irtHC3 | Mc02 |北卡罗来纳州埃夫兰| 36.027992 |-79.2212834 | 0 | 4 | 16 | 0 1249744 | 6352141 | 46 | 43522141 | 1 1249744 | WSMXT208L54YZIRTHC3 12402 |,3.0 0~1240 0 0 0 0 0 0 0 012444 4 0 0 0 0 012444 4 4 0 0 012444 7 7 7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 412444 4 4 4 4 4\12444 4 4 4 4 4 4 4 4\\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1| 1212444 4 412444 412444 4 412444 412444 412444 412444 412444 412444 4 412444 4 412444 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 412444 4 412444 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 14 | 0 | 3259744 | 6352141 | 46 | 24 | 0 | 5 | 15 | 0 | 3259744 | 6352141 | 46 | 0 | 66 | 0 | 0 1249744 | 6352141 | 1 | 3259744 | WSMxt208L54yZ5irtHC3 | Mc02 |埃夫兰,北卡罗来纳州| 36.027992 |-79.2212834 | 0 | 4 | 16 | 0 1249744 | 6352141 | 46 | 4CPListener.onReceived:4 1240 | 66 | 5 1249744ウMC12454;埃夫兰,3.0 0~1240 0 0 0 0 0 0 0 012444 4 0 0 0 0 012444 4 4 0 0 012444 7 7 7 7 7 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 4 4 4 4 4 4 4 412444 4 4 4 4 4\12444 4 4 4 4 4 4 4 4\\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1| 1212444 4 412444 412444 4 412444 412444 412444 412444 412444 412444 4 412444 4 412444 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 4 4 4 4 4 412444 4 412444 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4\12444 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 14 | 0 | 3259744 | 6352141 | 46 | 24 | 0 | 5 | 15 | 0 | 3259744 | 6352141 | 46 | 0 | 66 | 0 | 0 1249744 | 6352141 | 1 | 3259744 | WSMxt208L54yZ5irtHC3 | Mc02 |埃夫兰,北卡罗来纳州| 36.027992 |-79.2212834 | 0 | 4 | 16 | 0 1249744 | 6352141 | 46 | 4重新分析
4 | 0 | 66 | 5 | 0 | 3259744 | 6352141 | 1 | 3259744 | WSMxt208L54yZ5irtHC3 | Mc02 | efland,nc | 36.027992 |-79.221283“

您可以在Swift项目中使用目标C文件;在这些文件中,您可以使用普通C代码并生成一个使用
strrchr>的函数。然后您可以从Swift代码中调用该函数。

import Darwin

let str = "4|0|66|5|0|3259744|6352141|1|3259744"

func stringLastIndexOf(src:String, target:UnicodeScalar) -> Int? {
    let c = Int32(bitPattern: target.value)
    return src.withCString { s -> Int? in
        let pos = strrchr(s, c)
        return pos != nil ? pos - s : nil
    }
}

stringLastIndexOf(str, "|") // -> {Some 28}
stringLastIndexOf(str, ",") // -> nil

如果这样做是为了让所有子字符串都以“|”分隔,那么可以测试这种方法:

import Foundation

let s = "4|0|66|5|0|3259744|6352141|1|3259744|WSMxt208L54yZ5irtHC3|..."
let a = s.componentsSeparatedByString("|")
内置函数有时非常快,即使使用字符串,也可能获得所需的性能

如果确实需要只获取最后一个“|”的位置,可以使用utf16表示法,在utf16表示法中,在字符上前进应该更快

我认为这应该奏效:

let utf16String = s.utf16
var i = s.utf16Count - 1

while i >= 0 {
    if utf16String[i] == 124 {
        break
    }
    i--
}

println(i)

这里有一个快速的2.0答案

func lastIndexOf(s: String) -> Int? {
    if let r: Range<Index> = self.rangeOfString(s, options: .BackwardsSearch) {
        return self.startIndex.distanceTo(r.startIndex)
    }

     return Optional<Int>()
}

如果字符保证为单字节,数据量大且性能至关重要,则可能需要将其转换为字节数组(UInt8)并直接对其执行操作。然后,您可以将需要的部分转换回字符串


还请注意,优化的版本可能比调试版本快得多,因此您应该在打开Optimizer的情况下进行任何性能测试。目前还值得检查优化的版本是否太慢。

发布您的子字符串和代码索引!还请告诉我们使用
NSString
需要多长时间,这应该是最快的r而不是Swift
String
。您没有试图从“|”之间提取数据,是吗?如果问题没有指定字符宽度,这可能是可以接受的答案。对有用性进行了向上投票。
func testStringLastIndexOf() {
    let lastIndex = "0|2|45|7|9".lastIndexOf("|")

    XCTAssertEqual(lastIndex, 8)
}

func testStringLastIndexOfNotFound() {
    let lastIndex = "0123456789".lastIndexOf("|")

    XCTAssertEqual(lastIndex, nil);
}