0

I have a problem with generation of an array of substrings from a string in the following code

var primers=[String]()

var lengthOfPrimer = 20

var  lentghOfText = str1.characters.count

var rest = lentghOfText - lengthOfPrimer

for var i = 0; i <= str1.characters.count; ++i
{

var temp = rest - i

var substring1 = str1.substringWithRange(Range<String.Index>(start: advance(str1.startIndex, i), end: advance(str1.endIndex, -temp)))

primers.append(substring1)

}

In playground I have the following error at the line with the substring1 code – Execution was interrupted: reason: EXC_BAD_INSTRUCTION (code=EXC 1386_INVOP, subcode=0x0. In spite of error sign, I can see in playground the generated set of substrings in loop, but when I tried to use this code in program this code also did not work, What is wrong? What should I do?

2 Answers 2

2

Your error is coming from trying to advance the endIndex.

But how about something a little simpler? (Swift 2)

var first = str1.startIndex
var last = advance(first, 20 - 1, str1.endIndex)

while last != str1.endIndex {
    primers.append(str1[first++ ... last++])
}

print("\n".join(primers))

// output:
// ACAAGATGCCATTGTCCCCC
// CAAGATGCCATTGTCCCCCG
// AAGATGCCATTGTCCCCCGG
// AGATGCCATTGTCCCCCGGC
// GATGCCATTGTCCCCCGGCC
// ATGCCATTGTCCCCCGGCCT
// TGCCATTGTCCCCCGGCCTC
// GCCATTGTCCCCCGGCCTCC
// CCATTGTCCCCCGGCCTCCT
// CATTGTCCCCCGGCCTCCTG
// ATTGTCCCCCGGCCTCCTGC
// TTGTCCCCCGGCCTCCTGCT
// ...

Or the for loop way:

for var first = str1.startIndex, last = advance(first, 20 - 1, str1.endIndex);
    last != str1.endIndex;
    ++first, ++last
{
    primers.append(str1[first...last])
}
Sign up to request clarification or add additional context in comments.

7 Comments

Great, thanks for the working code! I have played with another for loop code and try to modify it as you can see below and it did not work. Sorry, I am new in swift and would like to understand why code did not work. Could you give me the explanation? for var i = 0; i < lengthOfText - 1; ++i { primers.append(str1[advance(str1.startIndex, i)...advance(str1.startIndex, i + 20) ] ) }
I would not recommend doing it that way. ++ for a string may be slow because it has to determine where the character boundary is. advance is like multiple ++s. So it's best to do it as little as possible. In my version above, I use ++ only twice per iteration.
You should also keep in mind what happens when the string is exactly 20 characters or shorter.
I have used your suggestion with C-like for-loop and now after coming deprecations of both C-like for-loop and ++ , I am using instead while-loop with .successor, but it works two time slower than the same while loop with ++. Is there way to improve the execution time of this while loop with .successor instead of ++ or no ?
Are you building/running the code with optimization on (-O)?
|
2
for var i = 0; i <= str1.characters.count; ++i

Without getting into the rest of this code, this for loop is wrong. You are reading past the end of the string because you are using <= when you should be using <.

Also you are calling str1.characters.count in the loop even though you have that value in a variable, which is slow.

Try:

for var i = 0; i < lengthOfText; ++i

2 Comments

I have tried, and it still not working with your correction.
Well yeah, you have other bugs too, I'm sure. I just pointed out the ones that jumped off the screen at me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.