Reorder string characters in Swift - string

So, let's say I have a String that is: "abc" and I want to change each character position so that I can have "cab" and later "bca". I want the character at index 0 to move to 1, the one on index 1 to move to 2 and the one in index 2 to 0.
What do I have in Swift to do this? Also, let's say instead of letters I had numbers. Is there any easier way to do it with integers?

Swift 2:
extension RangeReplaceableCollectionType where Index : BidirectionalIndexType {
mutating func cycleAround() {
insert(removeLast(&self), atIndex: startIndex)
}
}
var ar = [1, 2, 3, 4]
ar.cycleAround() // [4, 1, 2, 3]
var letts = "abc".characters
letts.cycleAround()
String(letts) // "cab"
Swift 1:
func cycleAround<C : RangeReplaceableCollectionType where C.Index : BidirectionalIndexType>(inout col: C) {
col.insert(removeLast(&col), atIndex: col.startIndex)
}
var word = "abc"
cycleAround(&word) // "cab"

In the Swift Algorithms package there is a rotate command
import Algorithms
let string = "abcde"
var stringArray = Array(string)
for _ in 0..<stringArray.count {
stringArray.rotate(toStartAt: 1)
print(String(stringArray))
}
Result:
bcdea
cdeab
deabc
eabcd
abcde

Related

Dynamic Programming - String, Substrings and Minimum Cost

Dear Computer Science experts,
I have a question regarding Dynamic Programming (DP). The problem is I am given a sentence of characters and a cost_list that contains a list of substrings of sentence with their costs, the goal is to find lowest cost. It is assumed that cost_list contains all the substrings in sentence.
For example, suppose I have the below parameters,
sentence = "xxxyyzz"
cost_list = [["x", 1], ["xx", 3], ["y", 3], ["yy", 1], ["z", 2]]
So sentence could be [xx][x][yy][z][z], so the total cost is 3 + 1 + 1 + 2 + 2 = 9
But I could also select the substrings in sentence in a different way and we have [x][x][x][yy][z][z], which gives us 1 + 1 + 1 + 1 + 2 + 2 = 8 and it is the lowest cost.
The question is to construct a Dynamic Programming algorithm find_lowest_cost(sentence, cost_list).
Below is my recursive function for this problem I created, I have tested and it is correct,
def find_lowest_cost(sentence, cost_list):
if len(sentence) == 0:
return 0
else:
result = []
possible_substrings = []
possible_costs = []
for c in cost_list:
current_substring = c[0]
current_cost = c[1]
if current_substring == sentence[0:len(current_substring)]:
possible_substrings.append(current_substring)
possible_costs.append(current_cost)
for i in range(0, len(possible_substrings)):
result.append(possible_costs[i] + find_lowest_cost(sentence[len(possible_substrings[i]):], cost_list))
return min(result)
sentence = "xxxyyzz"
cost_list = [["x", 1], ["xx", 3], ["y", 3], ["yy", 1], ["z", 2]]
print(find_lowest_cost(sentence, cost_list))
I am stuck on how to converting the Recursion to Dynamic Programming (DP).
Question 1: For DP table, my columns are the characters of sentence. How what should my rows be? My thinking is it can't be a rows of "x", "xx", "y", "yy" and "z" because how would we compare "yy" with, say only "y" in sentence?
Question 2: Suppose rows and columns are figured out, at the current cell, what should the current cell be built upon? My notion is the cell is built-upon the lowest value of previous cells, such as cell[row][col-1], cell[row-1][col] and cell[row-1][col-1]?
Thanks!
Once you are able to get the recursive solution then try to look for how many variable are getting changed. Analysing the recursive approach:
We need to find a solution like, what is the minimum cost when string is having length 1, then 2 so on... There would be repetitive calculation for substring from 0 to k th index so we need to store all calculated result into single dp so that we can give the answer of any k th index which has already calculated.
Below is my Java solution.
import java.util.HashMap;
public class MyClass {
private static Integer[] dp;
public static void main(String args[]) {
// cost_list = [["x", 1], ["xx", 3], ["y", 3], ["yy", 1], ["z", 2]]
HashMap<String, Integer> costmp = new HashMap();
costmp.put("x", 1);
costmp.put("xx", 3);
costmp.put("y", 3);
costmp.put("yy", 1);
costmp.put("z", 2);
String sentence = "xxxyyzz";
// String sentence = "xxyyzzxxxxyyyyxxxyxxyyyxxyyyzzzyyyxxxyyyyzzzyyyyxxxyyyzzzyyxxxxxxxxxxxxxxyyxyxyzzzzxxyyxx";
// String sentence = "xxxyyzzxxxxyyyyxxxyxxyyyxxyyyzzzyyyxxxyyyyzzzy";
dp = new Integer[sentence.length()+1];
int res = find_lowest_cost(sentence, costmp, 0);
System.out.println("find_lowest_cost = " + res);
}
private static int find_lowest_cost(String sentence, HashMap<String, Integer> costmp, int st)
{
if(st == sentence.length())
return 0;
int mincost = Integer.MAX_VALUE;
if(dp[st] != null)
return dp[st];
String str = new String();
for(int i = st;i < sentence.length(); i++)
{
str+=sentence.charAt(i);
if(!costmp.containsKey(str))
break;
int cost = costmp.get(str);
mincost = Math.min(mincost, cost+find_lowest_cost(sentence, costmp, i+1));
}
dp[st] = mincost;
return mincost;
}
}

DP Print (not count) all possible path classic climbing stair

I came across this classic question and found may many solution to it. for loop and DP/ reclusive + memorization.
Also found a twisted version of the questions asking to print all possible path instead of counting. Wondering for the twisted version, if we have DP solution ?
Q: If there are n stairs, you can either take 1 or 2 steps at a time, how may way can you finish the stairs. we can just using fib to calculate it. What if you are ask print out all possible ways(not revision please). For example, if n = 5. we have as solution. pseudo code is welcome or any language.
[1, 1, 1, 1, 1]
[1, 1, 1, 2]
[1, 1, 2, 1]
[1, 2, 1, 1]
[1, 2, 2]
[2, 1, 1, 1]
[2, 1, 2]
[2, 2, 1]
I have divided the solution into two subsections. First one using Memoization and the second one using Recursion.
Hope it helps!
Memoization Approach: It uses an array and calculates forward the solution based on base condition. I am using an array of type string array to store all the possible paths. To add a new path we are performing cartesian using Union.
Example:
To reach 1 we have path {1}
To reach 2 we have two paths {1, 2}
To reach 3 we have three paths {1 1 1, 1 2, 2 1} which is cartesian of above two paths.
Note: I have used two arrays just to make the solution understandable. We should be good with a single array.
Demo Memoization Approach
Full Program using Memoization Approach:
namespace Solutions
{
using System;
using System.Linq;
class Program
{
static void Main()
{
// Total Number of steps in stairs
var totalNumberOfSteps = 4;
// Total Number of allowed steps
var numberOfStepsAllowed = 2;
dynamic result = ClimbSteps(numberOfStepsAllowed, totalNumberOfSteps);
Console.WriteLine(result.Mem);
Console.WriteLine(string.Join(", ", result.Print));
Console.ReadLine();
}
private static dynamic ClimbSteps(int numberOfStepsAllowed, int totalNumberOfSteps)
{
var memList = Enumerable.Repeat(0, totalNumberOfSteps + 1).ToArray();
var printList = new string[totalNumberOfSteps + 1][];
if (numberOfStepsAllowed != 0)
{
memList[0] = 0;
printList[0] = new[] { "" };
memList[1] = 1;
printList[1] = new[] { "1" };
memList[2] = 2;
printList[2] = numberOfStepsAllowed > 1 ? new[] { "1 1", "2" } : new[] { "1 1" };
for (var indexTot = 3; indexTot <= totalNumberOfSteps; indexTot++)
{
for (var indexSteps = 1; indexSteps <= numberOfStepsAllowed && indexTot - indexSteps > 0; indexSteps++)
{
var indexTotalStep = indexTot;
var indexAllowedStep = indexSteps;
memList[indexTot] += memList[indexTot - indexSteps];
var cartesianValues = (from x in printList[indexSteps] from y in printList[indexTotalStep - indexAllowedStep] select x + " " + y)
.Union(from x in printList[indexSteps] from y in printList[indexTotalStep - indexAllowedStep] select y + " " + x).Distinct();
printList[indexTot] = printList[indexTot] == null
? cartesianValues.ToArray()
: printList[indexTot].Union(cartesianValues).Distinct().ToArray();
}
}
}
return new { Mem = memList[totalNumberOfSteps], Print = printList[totalNumberOfSteps] };
}
}
}
Output:
5
1 1 1 1, 1 1 2, 1 2 1, 2 1 1, 2 2
Recursive Approach
Demo Recursive Approach
Full Program using Recursive Approach:
namespace Solutions
{
using System;
class Program
{
static void Main()
{
// Total Number of steps in stairs
var totalNumberOfSteps = 4;
// Total Number of allowed steps
var numberOfStepsAllowed = 2;
ClimbSteps(numberOfStepsAllowed, totalNumberOfSteps);
Console.ReadLine();
}
private static void ClimbSteps(int numberOfStepsAllowed, int totalNumberOfSteps)
{
// Reach from [totalNumberOfSteps - [1..numberOfStepsAllowed]]
ClimbStep(stepsAllowed: numberOfStepsAllowed, totalNumberOfSteps: totalNumberOfSteps, currentStep: 0, stepsTaken: String.Empty);
}
private static void ClimbStep(int stepsAllowed, int totalNumberOfSteps, int currentStep, string stepsTaken)
{
if (currentStep == totalNumberOfSteps)
{
Console.WriteLine(stepsTaken);
}
for (int i = 1; i <= stepsAllowed && currentStep + i <= totalNumberOfSteps; i++)
{
ClimbStep(stepsAllowed, totalNumberOfSteps, currentStep + i, stepsTaken + i + " ");
}
}
}
}
Ouput:
1 1 1 1
1 1 2
1 2 1
2 1 1
2 2

Swift - Find character at several positions within string

In Swift, with the following string: "this is a string", how to obtain an array of the indexes where the character " " (space) is present in the string?
Desired result: [4,7,9]
I've tried:
let spaces: NSRange = full_string.rangeOfString(" ")
But that only returns 4, not all the indexes.
Any idea?
Here's a simple approach — updated for Swift 5.6 (Xcode 13):
let string = "this is a string"
let offsets = string
.enumerated()
.filter { $0.element == " " }
.map { $0.offset }
print(offsets) // [4, 7, 9]
How it works:
enumerated() enumerates the characters of the string
filter removes the characters for which the characters aren't spaces
map converts the array of tuples to an array of just the indices
A solution for Swift 1.2 using Regex
func searchPattern(pattern : String, inString string : String) -> [Int]?
{
let regex = NSRegularExpression(pattern: pattern, options: NSRegularExpressionOptions(), error: nil)
return regex?.matchesInString(string, options: NSMatchingOptions(), range: NSRange(location:0, length:count(string)))
.map { ($0 as! NSTextCheckingResult).range.location }
}
let string = "this is a string"
searchPattern("\\s\\S", inString : string) // [4, 7, 9]
searchPattern("i", inString : string) // [2, 5, 13]

Common Elements Sequence

I have two arrays of integer type.
int[] righttarray=new int[] {6,9,8,1,5,3};
int[] leftarray=new int[] {1,3};
Now I have to find out the common elements between these two as well as I need to match common elements indexes. If the indexes are same then its ok, if not then sequence will be maintained from rightarray.
I am getting Common elements by intersect method in C#.
See, element 1 and 3 are common in both the arrays. But in "leftarray" their sequence in 0,1 and in "rightarray" their sequence in 3,5. How to check this is my question. Thanks !!
Help me out doing this.
Ok, try something like:
int[] righttarray = new int[] { 6, 3, 8, 1, 5, 3 };
int[] leftarray = new int[] { 1, 3 };
if (righttarray.Length < leftarray.Length)
{
var result = righttarray.Where((x, i) => righttarray[i] == leftarray[i]);
}
else
{
var result = leftarray.Where((x, i) => leftarray[i] == righttarray[i]);
}
This will give you the number 3, which is in the same index and with the same element number. In your example, the output will be empty, I have changed only to check it ;)

Longest Substring Pair Sequence is it Longest Common Subsequence or what?

I have a pair of strings, for example: abcabcabc and abcxxxabc and a List of Common Substring Pairs (LCSP), in this case LCSP is 6 pairs, because three abc in the first string map to two abc in the second string. Now I need to find the longest valid (incrementing) sequence of pairs, in this case there are three equally long solutions: 0:0,3:6; 0:0,6:6; 3:0,6:6 (those numbers are starting positions of each pair in the original strings, the length of substrings is 3 as length of "abc"). I would call it the Longest Substring Pair Sequence or LSPQ. (Q is not to confuse String and Sequence)
Here is the LCSP for this example:
LCSP('abcabcabc', 'abcxxxabc') =
[ [ 6, 6, 3 ],
[ 6, 0, 3 ],
[ 3, 6, 3 ],
[ 0, 6, 3 ],
[ 3, 0, 3 ],
[ 0, 0, 3 ] ]
LSPQ(LCSP('abcabcabc', 'abcxxxabc'), 0, 0, 0) =
[ { a: 0, b: 0, size: 3 }, { a: 3, b: 6, size: 3 } ]
Now I find it with brute force recursively trying all combinations. So I am limited to about 25 pairs, otherwise it is unpractical. Size=[10,15,20,25,26,30], Time ms = [0,15,300,1000,2000,19000]
Is there a way to do that in linear time or at least not quadratic complexity so that longer input LCSP (List of Common Substring Pairs) could be used.
This problem is similar to the "Longest Common Subsequence", but not exactly it, because the input is not two strings but a list of common substrings sorted by their length. So I do not know where to look for an existing solutions or even if they exist.
Here is my particular code (JavaScript):
function getChainSize(T) {
var R = 0
for (var i = 0; i < T.length; i++) R += T[i].size
return R
}
function LSPQ(T, X, Y, id) {
// X,Y are first unused character is str1,str2
//id is current pair
function findNextPossible() {
var x = id
while (x < T.length) {
if (T[x][0] >= X && T[x][1] >= Y) return x
x++
}
return -1
}
var id = findNextPossible()
if (id < 0) return []
var C = [{a:T[id][0], b:T[id][1], size:T[id][2] }]
// with current
var o = T[id]
var A = C.concat(LSPQ(T, o[0]+o[2], o[1]+o[2], id+1))
// without current
var B = LSPQ(T, X, Y, id+1)
if (getChainSize(A) < getChainSize(B)) return B
return A
}

Resources