How to print all possible solutions for Longest Common subsequence - lcs

I want to print all the possible solutions to LCS problem.
The two strings abcbdab and bdcaba should print following 3 strings:
bdab,bcba,bcab.
C is the global matrix table which takes values according to algorithm and m, n are the length of the sequences a, b.
But The output is something unexpected.
#include<stdio.h>
#include<conio.h>
int co=0,m=0,n=0,c[10][10];
char a[10],b[10];
void main()
{
int i,j;
clrscr();
printf("Enter Two strings: ");
scanf("%s",a);
scanf("%s",b);
m=strlen(a);
n=strlen(b);
for(i=0;i<=m;i++)
{
for(j=0;j<=n;j++)
{ if(i==0 || j==0)
{
c[i][j]=0;
}
else if(a[i-1]==b[j-1])
{
c[i][j]=c[i-1][j-1]+1;
}
else if(c[i-1][j]>=c[i][j-1])
{
c[i][j]=c[i-1][j];
}
else
{
c[i][j]=c[i][j-1];
}
}
}
for(i=0;i<=m;i++)
{
for(j=0;j<=n;j++)
{
printf("%d\t",c[i][j]);
}
printf("\n");
}
print(m,n);
getch();
}
print(int i,int j)
{
if(i==0 || j==0)
return 0;
else if(a[i-1]==b[j-1])
{
print(i-1,j-1);
if(co==c[m][n])
{
co=0;
printf("\n");
}
printf("%c",a[i-1]);
co++;
}
else if(c[i-1][j]==c[i][j-1])
{
print(i-1,j);
print(i,j-1);
}
else if(c[i][j-1]>=c[i-1][j])
print(i,j-1);
else
print(i-1,j);
return;
}

Here you can find a recursive approach of how to do this: Reading out all LCSs
Here is my code for this approach in Java:
private Set<String> lcs(int[][] dp, String fst, String snd, int i, int j) {
Set<String> lcss = new HashSet<>();
if (i == 0 || j == 0) {
lcss.add("");
} else if (fst.charAt(i - 1) == snd.charAt(j - 1)) {
for (String lcs : lcs(dp, fst, snd, i - 1, j - 1)) {
lcss.add(lcs + fst.charAt(i - 1));
}
} else {
if (dp[i - 1][j] >= dp[i][j - 1]) {
lcss.addAll(lcs(dp, fst, snd, i - 1, j));
}
if (dp[i][j - 1] >= dp[i - 1][j]) {
lcss.addAll(lcs(dp, fst, snd, i, j - 1));
}
}
return lcss;
}

Here is the Java code with comments explaining how to print all possible lcs.
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
public class LongestCommonSubsequence {
public static int[][] LCSmatrix(String X, String Y) {
//we ignore the top most row and left most column in this matrix
//so we add 1 and create a matrix with appropriate row and column size
int m = X.length() + 1, n = Y.length() + 1;
int[][] c = new int[m][n];
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
//since we added 1 to row size and column size,
// we substract 1 from i,j to find the char at that index
if (X.charAt(i - 1) == Y.charAt(j - 1)) {
c[i][j] = c[i - 1][j - 1] + 1;
} else if (c[i - 1][j] >= c[i][j - 1]) {
c[i][j] = c[i - 1][j];
} else {
c[i][j] = c[i][j - 1];
}
}
}
printMatrix(c);
return c;
}
public static void printMatrix(int[][] grid) {
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[r].length; c++) {
System.out.print(grid[r][c] + " ");
}
System.out.println();
}
}
public static void allLCS(int[][] c, String X, String Y, int i, int j, Set<String> setLCS, String s) {
//return when either of the string length is 0
if (i == 0 || j == 0) {
setLCS.add(s);
return;
}
//if last characters are equal, they belong in lcs
if (X.charAt(i - 1) == Y.charAt(j - 1)) {
//prepend the char to lcs since, we are going backwards
s = X.charAt(i - 1) + s;
//continue finding lcs in substrings X.substring(0,i-1) and Y.substring(0,j-1)
allLCS(c, X, Y, i - 1, j - 1, setLCS, s);
} // if there is a tie in matrix cells, we backtrack in both ways,
// else one way, which ever is greater
else if (c[i - 1][j] == c[i][j - 1]) {
//continue finding lcs in substring X.substring(0,i-1)
allLCS(c, X, Y, i - 1, j, setLCS, s);
//continue finding lcs in substring Y.substring(0,j-1)
allLCS(c, X, Y, i, j - 1, setLCS, s);
} else if (c[i - 1][j] > c[i][j - 1]) {
allLCS(c, X, Y, i - 1, j, setLCS, s);
} else {
allLCS(c, X, Y, i, j - 1, setLCS, s);
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println(" Enter String X and Y : ");
String X = sc.next();
String Y = sc.next();
sc.close();
Set<String> set = new HashSet<String>();
allLCS(LCSmatrix(X, Y), X, Y, X.length(), Y.length(), set, "");
System.out.println(set.toString());
}
}

class Solution
{
public int function1(String s,String t,int n,int m,int dp[][]){
if(n==0 || m==0){
return 0;
}
if(dp[n][m]!=-1){
return dp[n][m];
}
if(s.charAt(n-1)==t.charAt(m-1)){
return dp[n][m]=1+function1(s,t,n-1,m-1,dp);
}
return dp[n][m]=Math.max(function1(s,t,n-1,m,dp),function1(s,t,n,m-1,dp));
}
public HashSet<String> function2(String s,String t,int n,int m,int dp[][],HashMap<String,HashSet<String>> map){
HashSet<String> temp=new HashSet<String>();
String key=n+"-"+m;
if(n==0 || m==0){
temp.add("");
return temp;
}
if(map.containsKey(key)){
return map.get(key);
}
if(s.charAt(n-1)==t.charAt(m-1)){
for(String tempstr:function2(s,t,n-1,m-1,dp,map)){
temp.add(tempstr+s.substring(n-1,n));
}
}
else{
if(dp[n-1][m]>=dp[n][m-1]){
temp.addAll(function2(s,t,n-1,m,dp,map));
}
if(dp[n-1][m]<=dp[n][m-1]){
temp.addAll(function2(s,t,n,m-1,dp,map));
}
}
map.put(key,temp);
return temp;
}
public List<String> all_longest_common_subsequences(String s, String t)
{
int n=s.length();
int m=t.length();
int dp[][]=new int[n+1][m+1];
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
dp[i][j]=-1;
}
}
function1(s,t,n,m,dp);
HashMap<String,HashSet<String>> map=new HashMap<String,HashSet<String>>();
ArrayList<String> ans=new ArrayList<String>(function2(s,t,n,m,dp,map));
Collections.sort(ans);
return ans;
}
}

Your source code is not printing the lcs. It is actually calculating the length of lcs. Source code given by you is totally wrong. First try to print one lcs. Then extend that solution to print all the lcs. For your help given below is working java solution.
static int arr[][];
static void lcs(String s1, String s2) {
for (int i = 1; i <= s1.length(); i++) {
for (int j = 1; j <= s2.length(); j++) {
if (s1.charAt(i - 1) == s2.charAt(j - 1))
arr[i][j] = arr[i - 1][j - 1] + 1;
else
arr[i][j] = Math.max(arr[i - 1][j], arr[i][j - 1]);
}
}
}
static Set<String> lcs(String s1, String s2, int len1, int len2) {
if (len1 == 0 || len2 == 0) {
Set<String> set = new HashSet<String>();
set.add("");
return set;
}
if (s1.charAt(len1 - 1) == s2.charAt(len2 - 1)) {
Set<String> set = lcs(s1, s2, len1 - 1, len2 - 1);
Set<String> set1 = new HashSet<>();
for (String temp : set) {
temp = temp + s1.charAt(len1 - 1);
set1.add(temp);
}
return set1;
} else {
Set<String> set = new HashSet<>();
Set<String> set1 = new HashSet<>();
if (arr[len1 - 1][len2] >= arr[len1][len2 - 1]) {
set = lcs(s1, s2, len1 - 1, len2);
}
if (arr[len1][len2 - 1] >= arr[len1 - 1][len2]) {
set1 = lcs(s1, s2, len1, len2 - 1);
}
for (String temp : set) {
set1.add(temp);
}
//System.out.println("In lcs" + set1);
return set1;
}
}
public static void main(String[] args) {
String s1 = "abcbdab";
String s2 = "bdcaba ";
arr = new int[s1.length() + 1][s2.length() + 1];
lcs(s1, s2);
System.out.println(lcs(s1, s2, s1.length(), s2.length()));
}
If last character of strings are equal then they must be in lcs. If they are not equal lcs will be either constructed from upper side of matrix or left side of matrix depending upon which value is greater. If both the value is equal then lcs will be constructed from both the side. So keep constructing the lcs until you have constructed all the lcs and store them in a set.

Related

Quick sort throws a 'not in inclusive range' error but sometimes it works. (Dart)

I have implemented a quick sort algorithm in Dart which sorts a list of random integers in the range from 0 to 100. Most of the times, it throws a 'not in inclusive range' exception. Other times, it works. I don't understand what is wrong with my code or logic here.
import 'dart:math';
List<int> list = [];
void main() {
randomize();
quickSort(0, list.length - 1);
print(list);
}
void randomize() {
for (int i = 0; i < 100; ++i) {
list.add(Random().nextInt(100));
}
}
void quickSort(int l, int h) {
if (l < h) {
int mid = partition(l, h);
quickSort(l, mid - 1);
quickSort(mid + 1, h);
}
}
int partition(int l, int h) {
int pivot = l;
int i = l;
int j = h;
while (i < j) {
while (list[i] <= list[pivot]) {
++i;
}
while (list[j] > list[pivot]) {
--j;
}
if (i < j) {
int temp = list[i];
list[i] = list[j];
list[j] = temp;
}
}
int temp = list[pivot];
list[pivot] = list[j];
list[j] = temp;
return j;
}

Dart store prime numbers in array

May I know how to store the N prime numbers, which I got from for loop in an array in dart?
import 'dart:io';
void main() {
// print('enter a start number');
// int a = int.parse(stdin.readLineSync()!);
print('enter a number');
int b = int.parse(stdin.readLineSync());
print('this are prime numbers');
primenum(b);
var z = '';
}
primenum(b) {
String string = "";
int a = 2;
outerLoop:
for (int i = a; i <= b; i++) {
for (int x = 2; x <= i / a; x++) {
if (i % x == 0) {
continue outerLoop;
}
}
var z = i.toString();
// print(z);
var h = z;
// String str = '';
string = string + h;
}
List d = string.split('');
print(d);
}
Using the above code, I am able to get those numbers in List. But the double-digit numbers are splitting.
May I know How to solve the above task? using dart.
The way you're doing string.split is splitting the string into a list of each individual character. Instead, you can add each prime number to a List directly without doing string manipulation.
primenum(b) {
List<String> d;
int a = 2;
outerLoop:
for (int i = a; i <= b; i++) {
for (int x = 2; x <= i / a; x++) {
if (i % x == 0) {
continue outerLoop;
}
}
d.add(i.toString());
}
print(d);
}

stack smashing in C code about making a histogram

I need to make a c program that will make a histogram of all the letters present in a phrase the user gives. When I run it, I does it but gives a "* stack smashing detected *: terminated". Where would this error be coming from? (for ease right now I set max to 3). In the future i'll have it find the max
Thank you
Andrew
#include <stdio.h>
#include <ctype.h>
#include <string.h>
static void ReadText(int histo[26],int max) {
char phrase[100];
int i;
char Letter;
char toArray;
// read in phrase
printf("Enter Phrase: "); // reads in phrase with spaces between words
scanf("%[^\n]",phrase);
// count the number of certain letters that occur
for(i = 0; i <= strlen(phrase);++i) {
Letter = phrase[i];
if(isalpha(Letter) != 0){
Letter = tolower(Letter);
toArray = Letter - 97;
histo[(int)toArray] = histo[(int)toArray] + 1;
}
}
}
static void DrawHist(int histo[26], int max){
int i;
int j;
int histo2[50];
for(i = 0; i <= 26; i++) {
histo2[i+i] = histo[i];
if(i < 25) {
histo2[i+i+1] = 0;
}
}
// (i = 1; i <= 50; i++) {
// printf("%d",histo2[i]);
//}
//printf("\n");
for(i=max;i>0;--i) {
for(j=0;j<=51;++j) {
if((j < 51) && (histo2[j] >= i)) {
printf("|");
}
else if((j < 51) && (histo2[j] < i)){
printf(" ");
}
else if(j == 51){
printf("\n");
}
}
}
printf("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-\n");
printf("A B C D E F G H I J K L M N O P Q R S T U V W X Y Z\n");
}
int main() {
int histo[26] = {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};
int max = 3;
//int i;
ReadText(histo,max);
//for(i = 0; i<26;++i) {
// printf("%d",histo[i]);
//}
DrawHist(histo,max);
return 0;
}

Calculate recursive EMA with burn period in Esper

As an exercise I am trying to calculate a recursive EMA with a burn period in Esper, EPL. It has moderately complex startup logic, and I thought this would be a good test for evaluating the sorts of things Esper could achieve.
Assuming a stream of values x1, x2, x3 at regular intervals, we want to calculate:
let p = 0.1
a = average(x1, x2, x3, x4, x5) // Assume 5, in reality use a parameter
y1 = p * x1 + (p - 1) * a // Recursive calculation initialized with look-ahead average
y2 = p * x2 + (p - 1) * y1
y3 = p * x3 + (p - 1) * y2
....
The final stream should only publish y5, y6, y7, ...
I was toying with a context that produces an event containing the average a, and that event triggers a second context that begins the recursive calculations. But by the time I try to get the first context to trigger once and once only, and the second context to handle the initial case using a and subsequent events recursively I end up with a messy tangle of logic.
Is there a straight-forward way to approach this problem?
(I'm ignoring using a custom aggregator, since this is a learning exercise)
This doesn't answer the question, but might be useful - implementation as a custom aggregation function, tested with esper 7.1.0
public class EmaFactory implements AggregationFunctionFactory {
int burn = 0;
#Override
public void setFunctionName(String s) {
// Don't know why/when this is called
}
#Override
public void validate(AggregationValidationContext ctx) {
#SuppressWarnings("rawtypes")
Class[] p = ctx.getParameterTypes();
if ((p.length != 3)) {
throw new IllegalArgumentException(String.format(
"Ema aggregation required three parameters, received %d",
p.length));
}
if (
!(
(p[0] == Double.class || p[0] == double.class) ||
(p[1] == Double.class || p[1] == double.class) ||
(p[2] == Integer.class || p[2] == int.class))) {
throw new IllegalArgumentException(
String.format(
"Arguments to Ema aggregation must of types (Double, Double, Integer), got (%s, %s, %s)\n",
p[0].getName(), p[1].getName(), p[2].getName()) +
"This should be made nicer, see AggregationMethodFactorySum.java in the Esper source code for " +
"examples of correctly dealing with multiple types"
);
}
if (!ctx.getIsConstantValue()[2]) {
throw new IllegalArgumentException(
"Third argument 'burn' to Ema aggregation must be constant"
);
}
;
burn = (int) ctx.getConstantValues()[2];
}
#Override
public AggregationMethod newAggregator() {
return new EmaAggregationFunction(burn);
}
#SuppressWarnings("rawtypes")
#Override
public Class getValueType() {
return Double.class;
}
}
public class EmaAggregationFunction implements AggregationMethod {
final private int burnLength;
private double[] burnValues;
private int count = 0;
private double value = 0.;
EmaAggregationFunction(int burn) {
this.burnLength = burn;
this.burnValues = new double[burn];
}
private void update(double x, double alpha) {
if (count < burnLength) {
value += x;
burnValues[count++] = x;
if (count == burnLength) {
value /= count;
for (double v : burnValues) {
value = alpha * v + (1 - alpha) * value;
}
// in case burn is long, free memory
burnValues = null;
}
} else {
value = alpha * x + (1 - alpha) * value;
}
}
#Override
public void enter(Object tmp) {
Object[] o = (Object[]) tmp;
assert o[0] != null;
assert o[1] != null;
assert o[2] != null;
assert (int) o[2] == burnLength;
update((double) o[0], (double) o[1]);
}
#Override
public void leave(Object o) {
}
#Override
public Object getValue() {
if (count < burnLength) {
return null;
} else {
return value;
}
}
#Override
public void clear() {
// I don't know when / why this is called - this part untested
count = 0;
value = 0.;
burnValues = new double[burnLength];
}
}
public class TestEmaAggregation {
private EPRuntime epRuntime;
private SupportUpdateListener listener = new SupportUpdateListener();
void send(int id, double value) {
epRuntime.sendEvent(
new HashMap<String, Object>() {{
put("id", id);
put("value", value);
}},
"CalculationEvent");
}
#BeforeEach
public void beforeEach() {
EPServiceProvider provider = EPServiceProviderManager.getDefaultProvider();
EPAdministrator epAdministrator = provider.getEPAdministrator();
epRuntime = provider.getEPRuntime();
ConfigurationOperations config = epAdministrator.getConfiguration();
config.addPlugInAggregationFunctionFactory("ema", EmaFactory.class.getName());
config.addEventType(
"CalculationEvent",
new HashMap<String, Object>() {{ put("id", Integer.class); put("value", Double.class); }}
);
EPStatement stmt = epAdministrator.createEPL("select ema(value, 0.1, 5) as ema from CalculationEvent where value is not null");
stmt.addListener(listener);
}
Double getEma() {
return (Double)listener.assertOneGetNewAndReset().get("ema");
}
#Test
public void someTest() {
send(1, 1);
assertEquals(null, getEma());
send(1, 2);
assertEquals(null, getEma());
send(1, 3);
assertEquals(null, getEma());
send(1, 4);
assertEquals(null, getEma());
// Last of the burn period
// We expect:
// a = (1+2+3+4+5) / 5 = 3
// y1 = 0.1 * 1 + 0.9 * 3 = 2.8
// y2 = 0.1 * 2 + 0.9 * 2.8
// ... leading to
// y5 = 3.08588
send(1, 5);
assertEquals(3.08588, getEma(), 1e-10);
// Outside burn period
send(1, 6);
assertEquals(3.377292, getEma(), 1e-10);
send(1, 7);
assertEquals(3.7395628, getEma(), 1e-10);
send(1, 8);
assertEquals(4.16560652, getEma(), 1e-10);
}
}

Tarjan algorithm based on BFS

I have an implemented BFS algorithm and I want to find SCC with Tarjan's algorithm using my BFS (implemented with colors and time method). Here is the code: /////////////////////////////////////////////////////////////
void dfs_visit_color(int v, Graf *G, int *time)
{
time++;
G->d[v] = *time;
G->color[v] = GRI;
NodeT *p = G->t[v];
int w;
printf("%d ", v);
while (p != NULL)
{
w = p->val;
if (G->color[w] == ALB)
{
T[w] = v;
dfs_visit_color(w, G, time);
}
p = p->next;
}
G->color[v] = NEGRU;
time++;
G->f[v] = *time;
}
void dfs_color(Graf *G){
int time = 0, i;
for (i = 0; i < G->n; i++)
{
if (G->color[i] = ALB);
}
for (i = 0; i < G->n; i++)
{
if (G->color[i] == ALB)
{
dfs_visit_color(i, G, &time);
}
}
}

Resources