How could i get O(m+n) using greedy? - analysis

How could I design an algorithm greedy O(m+n) for this case
Given two arrangements L1 and L2, where | L1 | = n and | L2 | = m.
L2 is said to be a subsequence of L1 if elements can be removed from L1 to get L2. This means that there are m indexes ik∈ [0..n] such that L1 [ik] = L2 [j] for each j∈ [0..m]. Design a greedy algorithm in O (n + m) that detects if L2 is a subsequence of L1 and outputs the ik indices in L1 in the case that L2 is a subsequence of L1.
Examples:
Input L1 = [1 2 3 4 5 6 7 8 9 10] L2 = [3 5 7 9] Output ik = [2 4 6 8]
Input L1 = [2 1 4 3 6 5 7 8 9 10] L2 = [1 6 5 10] Output ik = [1 4 5 9]
Input L1 = [1 2 3 4 5 6 7 8 9 10] L2 = [1 5 9 12] Output L2 is not subsequence of L1
I have been doing the classic code for this using this
bool isSubsequence(string str1, string str2) {
int i=0;
int j=0;
while (j<str1.length() && i<str2.length()){
if(str1[j]==str2[i]){
cout<<i<<" ";
j++;
}
i++;
}
return j==str1.length();
}
But i dont know how to get O(m+n) using greedy.
Thanks

Related

Combine Observables

Let say I have
A: IObservable<int>
B: IObservable<int>
how can I combine these two into
C: IObservable<int>
which emitted value is a product of last observed values of A and B?
E.g.
A = [ 2 3 1 ]
B = [ 2 5 6 ]
then
C = [ 4 6 15 18 6 ]
I'm not terribly good at f# (more like a novice), but this seems to work:
let a = new Subject<int>()
let b = new Subject<int>()
let c = Observable.CombineLatest(a, b, Func<_,_,_>(fun x y -> x * y))
c.Subscribe(fun x -> printfn "%i" x) |> ignore
a.OnNext(2)
b.OnNext(2)
a.OnNext(3)
b.OnNext(5)
b.OnNext(6)
a.OnNext(1)
I get:
4
6
15
18
6

Chunk (or partition) seq of items into sequences of N items [duplicate]

This question already has answers here:
F# split sequence into sub lists on every nth element
(8 answers)
F# array_chunk for Sequence
(13 answers)
Closed 8 years ago.
How should one implement a chunking (or partitioning) function for F# sequences? I'm looking for a function with this signature...
val toChunks : n:int -> sequence:seq<'T> -> seq<seq<'T>>
...which returns the items of the original sequence in groups of n items. The input sequence may be unending.
Simple Example
[1; 2; 3; 4; 5; 6; 7; 8; 9]
|> toChunks 4
|> Seq.iter (printfn "%A")
seq [1; 2; 3; 4]
seq [5; 6; 7; 8]
seq [9]
Nathan Evans suggested this solution:
/// Returns a sequence that yields chunks of length n.
let toChunks n (s:seq<'t>) = seq {
let pos = ref 0
let buffer = Array.zeroCreate<'t> n
for x in s do
buffer.[!pos] <- x
if !pos = n - 1 then
yield buffer |> Array.copy
pos := 0
else
incr pos
if !pos > 0 then
yield Array.sub buffer 0 !pos
}
It seems like the best approach to me, but I'd be interested in other solutions.

how to append every row of pandas dataframe to every row of another dataframe

for example, df1 is a 3*2 dataframe, and df2 is a 10*3 dataframe, what I want is to generate a new dataframe of 30*5, where each row in df1 is appended with the 3 columns of df2 for all 10 rows in df2.
I know I can use iteration to append columns of df2 to each row of df1, but I am wondering whether there are some more efficient way to do this in pandas, like its concat functions.
could anyone help?
regards,
nan
If I understand you, you need cartesian product. You can emulate this with merge in pandas:
>>> df1 = pd.DataFrame({'A':list('abc'), 'B':range(3)})
>>> df2 = pd.DataFrame({'C':list('defg'), 'D':range(3,7)})
>>> df1['key'] = 1
>>> df2['key'] = 1
>>> df = pd.merge(df1, df2, on='key')
>>> del df['key']
>>> df
A B C D
0 a 0 d 3
1 a 0 e 4
2 a 0 f 5
3 a 0 g 6
4 b 1 d 3
5 b 1 e 4
6 b 1 f 5
7 b 1 g 6
8 c 2 d 3
9 c 2 e 4
10 c 2 f 5
11 c 2 g 6

F# fails with "Error 4 This expression was expected to have type int but here has type int -> int"

Here is the code that I am trying to get to work last line is where it is failing:
let rec gcd a b =
if b= 0 then
a
else
gcd b (a % b);;
let n = 8051
let mutable d = 0
let mutable c = 1
let mutable xi = 2
let mutable yi = 2
let f x = (pown x 2) + (c % n);;
while c < 100 do
while d = 1 do
xi <- (f xi)
yi <- (f(f(yi)))
printfn "%d%d" xi yi
d <- gcd(abs (xi - yi) n)
---------------------The Following Code works; Except for integer overflow on N---------
module Factorization
let rec gcd a b =
if b= 0 then
a
else
gcd b (a % b);;
let n = 600851475143N
let mutable d, c, xi, yi = 1, 1, 2, 2
let f x = (pown x 2) + (c % n);;
let maxN m =int(ceil(sqrt(float m)))
//if (n > maxN(xi)) && (n > maxN(yi)) then
while c < 100 do
d <- 1
while d = 1 do
if (maxN(n) > xi) && (maxN(n) > yi) then
xi <- f xi
yi <- f(f(yi))
d <- gcd (abs (xi - yi)) n
//fail
if d = n then d<-1
if d <> 1 then printfn "A prime factor of %d x = %d, y = %d, d = %d" n xi yi d
else
xi <- 2
yi <- 2
c <- c + 1;;
In addition to what #Rangoric pointed out, the outer brackets have to go as well otherwise currying won't work:
d <- gcd (abs(xi-yi)) n
Yikes, here are a few unsolicited tips (#BrokenGlass answered the question itself correctly).
First, you can assign all those mutables in one line:
let mutable d, c, xi, yi = 0, 1, 2, 2
Second, go easy on the parentheses:
xi <- f xi
yi <- f (f yi)
And of course, try to get rid of the mutables and while loops. But I'll leave that to you since I'm sure you are aware seeing that you implemented gcd using recursion.
Try:
d <- gcd (abs(xi-yi)) n
It is pointing out that abs is a int->int and not an int by itself. Wrapping it in parentheses causes the abs to be executed before gcd looks at it. This causes gcd to see the result of abs instead of abs itself.

F# Seq.initInfinite giving StackOverflowException

I'm learning F#, and I am having trouble understanding why this crashes. It's an attempt to solve Project Euler problem 2.
let rec fibonacci n =
if n = 1 then
1
elif n = 2 then
2
else
fibonacci (n - 1) + fibonacci (n - 2)
let debugfibonacci n =
printfn "CALC: %d" n
fibonacci n
let isEven n =
n % 2 = 0
let isUnderLimit n =
n < 55
let getSequence =
//[1..30]
Seq.initInfinite (fun n -> n)
|> Seq.map debugfibonacci
|> Seq.filter isEven
|> Seq.takeWhile isUnderLimit
Seq.iter (fun x -> printfn "%d" x) getSequence
The final version would call a sum function (and would have a higher limit than 55), but this is learning code.
As is, this gives a StackOverflowException. However, if I comment in the [1..30] and comment out the Seq.initInfinite, I get:
CALC: 1
CALC: 2
2
CALC: 3
CALC: 4
CALC: 5
8
CALC: 6
CALC: 7
CALC: 8
34
CALC: 9
CALC: 10
CALC: 11
It appears to be generating items on demand, as I would expect in LINQ. So why does it blow up when used with initInfinite?
Seq.initInfinite returns a sequence that starts at 0.
Your fibonacci function results in a stack overflow when called with zero, because it never hits the terminating cases.
You can solve this by starting from Seq.initInfinite (fun n -> n + 1)
You're starting with 0 with initInfinite, which then recurses -1, -2, ...
(By the way, if you're using the Visual Studio debugger, this is easy to diagnose, by checking the call stack and locals window.)

Resources