Find two Binary Tree are structurally identical - data-structures

I was recently asked in the interview
What would be the efficient algorithm to find if two given binary trees are structurally identical but not the content?
a
/ \
b c
\
e
z
/ \
u v
\
t
are structurally identical.
Next question was find out if 2 binary tree are structurally mirror ?
Any pointer or help are appreciated.
My attempt was
boolean isStrucutrallyIdentitical(BinaryNode root1, BinayNode root2) {
if(root1==null && root2==null) return true;
if(root1==null || root2==null) return false;
if(root1!=null && roo2!=null) return true; // instead of value just check if its null or not
return isStrucutrallyIdentitical(root1.getLeft(), root2.getLeft()) && isStrucutrallyIdentitical(root1.getRight(), root2.getRight());
}

public boolean areStructuralySame(TreeNode<Integer> tree1, TreeNode<Integer> tree2) {
if(tree1 == null && tree2 == null) {
return true;
}
if(tree1 == null || tree2 == null) {
return false;
} else return (areStructuralySame(tree1.getLeft(), tree2.getLeft()) && areStructuralySame(tree1.getRight(), tree2.getRight()));
}
This works fine

private static boolean compare(TNode curRoot, TNode newRoot) {
if (curRoot == null && newRoot == null) {
return true;
} else if ((curRoot == null && newRoot != null) || (curRoot != null && newRoot == null))
return false;
else {
if (compare(curRoot.left, newRoot.left) && compare(curRoot.right, newRoot.right))
return true;
return false;
}
}

Related

Check if 2 trees have the same structure

Only passing an object of type BST NOT of type Node,the logic here is wrong i want some help with it, it always return false
bool BST<T>::similarStructure(BST<T>& Tree2) {
if (isEmpty()) {
cout << "tree is empty\n";
return;
}
StackArray<node<T>> *s1, *s2; // s1 for traversal,, s2 for printing
s1->Push(root);
s2->Push(tree2.root);
while (!s1.IsEmpty() &&!s2.isempty()) {
node<T> n = s1->Pop();
node<T> n1=s2->Pop();
if (n->right != NULL && n1->right!=NULL){
s1.Push(n->right);
s2.Push(n1->right); }
else{
return false;}
if (n->left != NULL && n->left!=NULL){
s1.Push(n->left);
s2.Push(n1->left);}
else{
return false;}
}
return true;
}
Take the simplest situation as example, that the lhs tree and rhs tree both have only one node.
Inside the while loop, when hit the first condition expression, if (n->right != NULL && n1->right!=NULL), since n->right == NULL, the expression evaluate false value, thus return false for this function.

Partition a graph by vertex label

I am working on a problem that requires to partition a directed labeled graph into several subgraphs. In each of the subgraph, the nodes are connected and they have the same label. Is there an efficient algorithm to solve this?
Here is my solution implemented in Java, it uses JGraphT as the graph library.
private Set<Set<Node>> partition(DirectedGraph<Node, Edge> graph) {
Map<Node, Set<Node>> map = new HashMap<Node, Set<Node>>();
for (Edge edge : graph.edgeSet()) {
Node source = graph.getEdgeSource(edge);
Node target = graph.getEdgeTarget(edge);
if (source.getLabel().equals(target.getLabel())) {
if (map.get(source) != null && map.get(target) == null) {
map.get(source).add(target);
map.put(target, map.get(source));
} else if (map.get(target) != null && map.get(source) == null) {
map.get(target).add(source);
map.put(source, map.get(target));
} else if (map.get(source) == null && map.get(target) == null) {
Set<Node> set = new HashSet<Node>();
set.add(source);
set.add(target);
map.put(source, set);
map.put(target, set);
} else {
Set<Node> sourceSet = map.get(source);
Set<Node> targetSet = map.get(target);
sourceSet.addAll(targetSet);
for(Node n : targetSet){
map.put(n,sourceSet);
}
targetSet = null;
}
} else {
if (map.get(source) == null) {
Set<Node> set = new HashSet<Node>();
set.add(source);
map.put(source, set);
}
if (map.get(target) == null) {
Set<Node> set = new HashSet<Node>();
set.add(target);
map.put(target, set);
}
}
Collection<Set<Node>> values = map.values();
}
return new HashSet<Set<Node>>(map.values());
}

How to make the given method generic ? Is it a good idea to make it generic in terms of performance?

private IQueryable<Customer> FilterResult(string search, List<Customer> dtResult, List<string> columnFilters)
{
IQueryable<Customer> results = dtResult.AsQueryable();
results = results.Where(p =>
(
search == null ||
(
p.Name != null && p.Name.ToLower().Contains(search.ToLower())
|| p.City != null && p.City.ToLower().Contains(search.ToLower())
|| p.Postal != null && p.Postal.ToLower().Contains(search.ToLower())
|| p.Email != null && p.Email.ToLower().Contains(search.ToLower())
|| p.Company != null && p.Company.ToLower().Contains(search.ToLower())
|| p.Account != null && p.Account.ToLower().Contains(search.ToLower())
|| p.CreditCard != null && p.CreditCard.ToLower().Contains(search.ToLower())
)
)
&& (columnFilters[0] == null || (p.Name != null && p.Name.ToLower().Contains(columnFilters[0].ToLower())))
&& (columnFilters[1] == null || (p.City != null && p.City.ToLower().Contains(columnFilters[1].ToLower())))
&& (columnFilters[2] == null || (p.Postal != null && p.Postal.ToLower().Contains(columnFilters[2].ToLower())))
&& (columnFilters[3] == null || (p.Email != null && p.Email.ToLower().Contains(columnFilters[3].ToLower())))
&& (columnFilters[4] == null || (p.Company != null && p.Company.ToLower().Contains(columnFilters[4].ToLower())))
&& (columnFilters[5] == null || (p.Account != null && p.Account.ToLower().Contains(columnFilters[5].ToLower())))
&& (columnFilters[6] == null || (p.CreditCard != null && p.CreditCard.ToLower().Contains(columnFilters[6].ToLower())))
);
return results;
}
This is the method which I am using for datatable filter , Here my question is can I make it as generic ? I feel it can be using reflection. But does that affect to performance as well ?
thx in advance..
I have done till it so far :
private IQueryable<T> FilterResult<T>(string search, IQueryable<T> dtResult, List<string> columnFilters)
{
IQueryable<T> results = dtResult;
Type typeParameterType = typeof(T); // this will give me the class detail which I have passed
// 1 How to extract all property of this class to use in where clause
// 2 How I can use it either dynamic linq , foreach or any possible solution.
//1
PropertyInfo[] properties = typeParameterType.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var item in properties)
{
// This will be changed after some validation logic
string predicate = item.Name + " = " + search;
results = results.Where(predicate);
}
return results;
}
I'm not familiar (and don't intend to use) dynamic LINQ. In this case you don't really need such thing. As I said I would not pass in a list of string as column filters, it makes code longer and the order can matter and cause hard-to-debug issues. Here is the code I've just come up with, you can try and I'm not sure it works but if any please let me know:
private IEnumerable<T> FilterResult<T>(string search, IQueryable<T> dtResult, params ColumnFilter<T>[] filters)
{
var propGetters = typeof(T).GetProperties().Where(p => p.PropertyType == typeof(string))
.Select(p => new Func<object,string>((item) => ((p.GetValue(item, null) as string) ?? "").ToLower())).ToList();
if(!string.IsNullOrEmpty(search)) {
Func<T,bool> predicate = e => propGetters.Aggregate(false, (c,o) => c || o(e));
dtResult = dtResult.Where(predicate).AsQueryable();
}
return filters.Aggregate(dtResult.AsEnumerable(), (c,e) => c.Where(o => e.IsOK(o));
}
public class ColumnFilter<T> {
public ColumnFilter(Func<T,string> selector, string term = ""){
PropertySelector = selector;
Term = term;
}
public Func<T,string> PropertySelector {get;set;}
public string Term {get;set;}
public bool IsOK(T item) {
return PropertySelector(item).Contains(Term);
}
}
Usage:
FilterResult(yourSearch, yourDtResult, new ColumnFilter(e=>e.City, "someCitySearch"),
new ColumnFilter(e=>e.Postal, "somePostalSearch"), ...);
If you still want to stick to List for columnFilters, the code can be modified but it will be surely longer.

How to unit test a jpa repository method?

I have coded a JPA repository method and I am now realizing it is impossible to unit test.
Can anyone please advise how to unit test the following method or how to refactor my repository so that it is unit-testable?
Here is the problematic method:
#Override
public List<Pli> findPlisByMultiField(String identifiant, Date dateReceptionFrom, Date dateReceptionTo, PaiementEnum paiement, AREnum ar, String numeroAR, FDVEnum FDV, ConteneurNum conteneurNum, StatutPli statut) {
log.debug("findPlisByMultiField");
CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<Pli> c = criteriaBuilder.createQuery(Pli.class);
Root<Pli> pli = c.from(Pli.class);
List<Predicate> criteria = new ArrayList<Predicate>();
if (identifiant != null && !identifiant.trim().equals("")) {
ParameterExpression<String> parameterIdentifiant = criteriaBuilder.parameter(String.class, "identifiant");
Predicate conditionIdentifiant = criteriaBuilder.like(pli.<String> get("identifiant"), parameterIdentifiant);
criteria.add(conditionIdentifiant);
}
if (dateReceptionFrom != null && dateReceptionTo != null) {
ParameterExpression<Date> parameterDateReceptionFrom = criteriaBuilder.parameter(Date.class, "dateReceptionFrom");
ParameterExpression<Date> parameterDateReceptionTo = criteriaBuilder.parameter(Date.class, "dateReceptionTo");
Predicate conditionDateReception = criteriaBuilder.between(pli.<Date> get("dateReception"), parameterDateReceptionFrom, parameterDateReceptionTo);
criteria.add(conditionDateReception);
}
if (paiement != null) {
if (paiement.equals(PaiementEnum.IsPaiement)) {
Predicate conditionPaiementEnum = criteriaBuilder.equal(pli.<PaiementEnum> get("paiement"), true);
criteria.add(conditionPaiementEnum);
} else {
Predicate conditionPaiementEnum = criteriaBuilder.equal(pli.<PaiementEnum> get("paiement"), false);
criteria.add(conditionPaiementEnum);
}
}
if (ar != null) {
if (ar.equals(AREnum.IsAR)) {
Predicate conditionAREnum = criteriaBuilder.equal(pli.<AREnum> get("AR"), true);
criteria.add(conditionAREnum);
} else {
Predicate conditionAREnum = criteriaBuilder.equal(pli.<AREnum> get("AR"), false);
criteria.add(conditionAREnum);
}
}
if (numeroAR != null && !numeroAR.trim().equals("")) {
ParameterExpression<String> parameterNumeroAR = criteriaBuilder.parameter(String.class, "numeroAR");
Predicate conditionNumeroAR = criteriaBuilder.like(pli.<String> get("numeroAR"), parameterNumeroAR);
criteria.add(conditionNumeroAR);
}
if (FDV != null) {
if (FDV.equals(FDVEnum.IsFDV)) {
Predicate conditionFDVEnum = criteriaBuilder.equal(pli.<FDVEnum> get("FDV"), true);
criteria.add(conditionFDVEnum);
} else {
Predicate conditionFDVEnum = criteriaBuilder.equal(pli.<FDVEnum> get("FDV"), false);
criteria.add(conditionFDVEnum);
}
}
if (conteneurNum != null) {
ParameterExpression<ConteneurNum> parameterConteneurNum = criteriaBuilder.parameter(ConteneurNum.class, "conteneurNum");
Predicate conditionConteneurNum = criteriaBuilder.equal(pli.<ConteneurNum> get("conteneurNum"), parameterConteneurNum);
criteria.add(conditionConteneurNum);
}
if (statut != null) {
ParameterExpression<StatutPli> parameterStatut = criteriaBuilder.parameter(StatutPli.class, "statut");
Predicate conditionStatut = criteriaBuilder.equal(pli.<StatutPli> get("statut"), parameterStatut);
criteria.add(conditionStatut);
}
if (criteria.size() == 0) {
return Pli.findAllPlis();
} else if (criteria.size() == 1) {
c.where(criteria.get(0));
} else {
c.where(criteriaBuilder.and(criteria.toArray(new Predicate[0])));
}
TypedQuery<Pli> q = em.createQuery(c);
if (identifiant != null && !identifiant.trim().equals("")) {
q.setParameter("identifiant", "%" + identifiant + "%");
}
if (dateReceptionFrom != null && dateReceptionTo != null) {
q.setParameter("dateReceptionFrom", dateReceptionFrom);
q.setParameter("dateReceptionTo", dateReceptionTo);
}
if (numeroAR != null && !numeroAR.trim().equals("")) {
q.setParameter("numeroAR", "%" + numeroAR + "%");
}
if (conteneurNum != null) {
q.setParameter("conteneurNum", conteneurNum);
}
if (statut != null) {
q.setParameter("statut", statut);
}
return q.getResultList();
}
Well, I don't think you will be able to Unit Test it as it's strictly specified, but you can make a test using an in memory database (look out for HSQL) so that the app don't need to actually go to the real database just for testing.
That way you will be able to create an automated test that could run inside JUnit for example, mocking maybe only some of the methods.

LINQ TO SQL, Dynamic query with DATE type fields

I'm building a query with the LINQ dynamic library so I don't know how many potential parameters will I have and I get an error when trying to query DATE type fields:
Operator '>=' incompatible with operand types 'DateTime' and 'String'
When I step through the debugger in the Dynamic.cs it shows that the value is of type string and the field is of type date so the problem is obvious but I have no idea how to approach it.
Any ideas?
BR
Code:
using (MyEntities db = new MyEntities())
{
String SQLparam = "CreateDate >= \"" + DateTime.Now.ToShortDateString() + "\"";
List<UserList> UserList = db.UserList.Where(SQLparam).ToList();
}
You have to use a parameterized query, e.g.
using (MyEntities db = new MyEntities())
{
String SQLparam = "CreateDate >= #1";
List<UserList> UserList = db.UserList.Where(SQLparam, new [] { DateTime.Now }).ToList();
}
I had the same problem, but with Boolean as well, so I generalised the solution
Expression ConstantParser<T>(Expression left, Token op, Expression right, Func<string, T> parser)
{
if (right is ConstantExpression)
{
try
{
var value = ((ConstantExpression)right).Value.ToString();
return Expression.Constant(parser(value));
}
catch (Exception)
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
The lines in the main function then become...
else if (left.Type == typeof(DateTime) && right.Type == typeof(string))
{
right = this.ConstantParser(left, op, right, DateTime.Parse);
}
else if (left.Type == typeof(DateTime?) && right.Type == typeof(string))
{
right = this.ConstantParser(left, op, right, x => { DateTime? t = DateTime.Parse(x); return t; });
}
else if (left.Type == typeof(Boolean) && right.Type == typeof(string))
{
right = this.ConstantParser(left, op, right, Boolean.Parse);
}
Only disadvantage I can see to this approach is that if the Parse fails, we will raise and exception, but given that we throw one anyway, I don't see that it matters too much
I was in the same boat and I was able to solve this by changing one method in the Dynamic Library. It's a hack, but it allows me to use dates in expressions with equality operators (=,>,<, etc..).
I'm posting the code here in case someone still cares.
The code I added is in the if block around line 53
else if (left.Type == typeof(DateTime) && right.Type == typeof(string))
{
if (right is ConstantExpression)
{
DateTime datevalue;
string value = ((ConstantExpression) right).Value.ToString();
if (DateTime.TryParse(value, out datevalue))
{
right = Expression.Constant(datevalue);
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
The code basically checks if you are trying to compare a date field (left) with a string (right). And then it converts the right expression to a date constant
Here is the whole ParseComparison method:
// =, ==, !=, <>, >, >=, <, <= operators
Expression ParseComparison()
{
Expression left = ParseAdditive();
while (token.id == TokenId.Equal || token.id == TokenId.DoubleEqual ||
token.id == TokenId.ExclamationEqual || token.id == TokenId.LessGreater ||
token.id == TokenId.GreaterThan || token.id == TokenId.GreaterThanEqual ||
token.id == TokenId.LessThan || token.id == TokenId.LessThanEqual)
{
Token op = token;
NextToken();
Expression right = ParseAdditive();
bool isEquality = op.id == TokenId.Equal || op.id == TokenId.DoubleEqual ||
op.id == TokenId.ExclamationEqual || op.id == TokenId.LessGreater;
if (isEquality && !left.Type.IsValueType && !right.Type.IsValueType)
{
if (left.Type != right.Type)
{
if (left.Type.IsAssignableFrom(right.Type))
{
right = Expression.Convert(right, left.Type);
}
else if (right.Type.IsAssignableFrom(left.Type))
{
left = Expression.Convert(left, right.Type);
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
}
else if (IsEnumType(left.Type) || IsEnumType(right.Type))
{
if (left.Type != right.Type)
{
Expression e;
if ((e = PromoteExpression(right, left.Type, true)) != null)
{
right = e;
}
else if ((e = PromoteExpression(left, right.Type, true)) != null)
{
left = e;
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
}
else if (left.Type == typeof(DateTime) && right.Type == typeof(string))
{
if (right is ConstantExpression)
{
DateTime datevalue;
string value = ((ConstantExpression) right).Value.ToString();
if (DateTime.TryParse(value, out datevalue))
{
right = Expression.Constant(datevalue);
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
CheckAndPromoteOperands(isEquality ? typeof(IEqualitySignatures) : typeof(IRelationalSignatures),
op.text, ref left, ref right, op.pos);
}
switch (op.id)
{
case TokenId.Equal:
case TokenId.DoubleEqual:
left = GenerateEqual(left, right);
break;
case TokenId.ExclamationEqual:
case TokenId.LessGreater:
left = GenerateNotEqual(left, right);
break;
case TokenId.GreaterThan:
left = GenerateGreaterThan(left, right);
break;
case TokenId.GreaterThanEqual:
left = GenerateGreaterThanEqual(left, right);
break;
case TokenId.LessThan:
left = GenerateLessThan(left, right);
break;
case TokenId.LessThanEqual:
left = GenerateLessThanEqual(left, right);
break;
}
}
return left;
}
Because I had to make a comparison for a DateTime? and I had make this modification.
else if (left.Type == typeof(DateTime?) && right.Type == typeof(string))
{
if (right is ConstantExpression)
{
DateTime datevalue;
string value = ((ConstantExpression)right).Value.ToString();
if (DateTime.TryParse(value, out datevalue))
{
DateTime? nullableDateValue = datevalue;
right = Expression.Constant(nullableDateValue, typeof(DateTime?));
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
else
{
throw IncompatibleOperandsError(op.text, left, right, op.pos);
}
}
Thanks for the tip!

Resources