i want to create generic list from string - algorithm

i want to create generic list from string
input string is (a(b,c,u),d,e(f),g(),h,i(j(k,l,m(n))),r)
my class is
public class Node
{
public string Name; // method name
// public decimal Time; // time spent in method
public List<Node> Children;
}
child node is represent in ().
Example: a is parent node and b,c u are child nodes; will be saved in List<Node> in the same way as its parent which has j as child and k,l and m as children j.
it is similary like tree
<.>
|---<a>
| |--- b
| |--- c
| |--- u
|--- d
|---<e>
| |--- f
|---<g>
|--- h
|---<i>
| |---<j>
| | |--- k
| | |--- l
| | |---<m>
| | | |--- n
|--- r

The end result for you Node data structure will end up looking similar to a tree. To achieve what you want you could use a recursive function.
Here is an example of such a function (with comments):
//Recursive Function that creates a list of Node objects and their
//children from an input string
//Returns: List of Nodes
//Param string input: The input string used to generate the List
//Param int index: The index to start looping through the string
public List<Node> CreateNodeList(string input, int index)
{
List<Node> nodeList = new List<Node>();
Node currentNode = new Node();
StringBuilder nameBuilder = new StringBuilder();
//Start looping through the characters in the string at the
//specified index
for(int i = index; i < array.size; i++)
{
switch(input[i])
{
//If we see an open bracket we need to use the
//proceeding list to create the current nodes children
//We do this by recursively calling this function
//(passing the input string and the next index as
//parameters) and setting the children property to b
//the return value
case ‘(‘:
currentNode.Children = CreateNodeList(input, i+1);
i = input.IndexOf(‘)’, i);
break;
//If we see a closed bracket we create a new Node based
//of the existing string, add it to the list, and then
//return the list
case ‘)’:
currentNode.Name = nameBuilder.ToString();
nodeList.Add(currentNode);
nameBuilder.Clear();
return nodeList;
//if we see a comma we create a new node object based
//off the current string and add it to the list
case ‘,’:
currentNode.Name = nameBuilder.ToString();
nodeList.Add(currentNode);
nameBuilder.Clear();
currentNode = new Node();
break;
//Any other character we see must be for the name
//of a node, so we will append it to our string
//builder and continue looping
default:
nameBuilder.Append(input[i]);
}
}
//We will probably never reach here since your input string
//usually ends in ‘)’ but just in case we finish by returning
//the list
return nodeList;
}
//An example of how to use this recursive function
public static void main()
{
//Your input string
string input = “(a(b,c,u),d,e(f),g(),h,i(j(k,l,m(n))),r)”;
//Call our function with the input string and 1 as arguments
//We use 1 to skip the first ‘(‘ which is a index 0
List<Node> nodeList = CreateNodeList(input, 1);
//Do stuff with list here
}
This function keeps track of characters for the names of nodes, creating new ones and adding them to the list every time it sees a ',' or ')' (returning the List when seeing a ')')) and it also populates a Nodes children when it sees a '(' character by recursively calling the function and using its return value. The one major downside being you have keep track off the index you're on.
This function was written free hand but it's meant to be very similiar to C# (you didn't specify a language so I hope this helps.)
I hope this helps and is what your'e looking for :)

Related

Building binary tree using Java Stream. Is it possible in Java Stream sorting while reduce?

I want to build a Huffman tree from input string using Java Stream.
This is how I do it right now.
Class MyNode with all needed Constructors:
public static class MyNode {
Character value;
MyNode left;
MyNode right;
long freq;
...
}
Reading a line and getting List of MyNodes:
Scanner scan = new Scanner(System.in);
String input = scan.next();
List<MyNode> listOfNodes = input.chars().boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.stream().sorted(Comparator.comparingLong(Map.Entry::getValue))
.map(x -> new MyNode((char)x.getKey().intValue(), x.getValue()))
.collect(Collectors.toList());
This while loop I want to replace with something from Stream:
while (listOfNodes.size() > 1) {
MyNode first = listOfNodes.get(0);
MyNode second = listOfNodes.get(1);
listOfNodes.remove(first);
listOfNodes.remove(second);
listOfNodes.add(new MyNode(first.freq + second.freq, first, second));
listOfNodes.sort(Comparator.comparingLong(MyNode::getFreq));
}
In while loop I build tree like this
The first idea was to use Stream reduce, but then I need to sort resulting list after every reduce.
This is not a task that benefits from using the Stream API. Still, there are ways to improve it.
Sorting the entire list just for the sake of inserting a single element, bear an unnecessary overhead. Since the list is sorted to begin with, you can use binary search to efficiently find the correct insertion position so that the list stays sorted:
while(listOfNodes.size() > 1) {
MyNode first = listOfNodes.remove(0), second = listOfNodes.remove(0);
MyNode newNode = new MyNode(first.freq + second.freq, first, second);
int pos = Collections.binarySearch(listOfNodes, newNode,
Comparator.comparingLong(MyNode::getFreq));
listOfNodes.add(pos<0? -pos-1: pos, newNode);
}
Note that you could make this code more efficient by reversing the order so that you will remove from the end of the list (which will be an ArrayList in practice).
But the better alternative is to use a data structure which is sorted to begin with, e.g.
PriorityQueue<MyNode> queueOfNodes = input.chars().boxed()
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream()
.map(x -> new MyNode((char)x.getKey().intValue(), x.getValue()))
.collect(Collectors.toCollection(
() -> new PriorityQueue<>(Comparator.comparingLong(MyNode::getFreq))));
MyNode result = queueOfNodes.remove();
while(!queueOfNodes.isEmpty()) {
MyNode second = queueOfNodes.remove();
queueOfNodes.add(new MyNode(result.freq + second.freq, result, second));
result = queueOfNodes.remove();
}

Trie implementation with wildcard values

I'm implementing an algorithm to do directory matching. So I'm given a set of valid paths that can include wildcards (denoted by "X"). Then when I pass in an input I need to know if that input matches with one of the paths in my valid set. I'm running into a problem with the wildcards when a wildcard value that is passed in actually matches with another valid value. Here is an example:
Set of valid paths:
/guest
/guest/X
/X/guest
/member
/member/friends
/member/X
/member/X/friends
Example input:
/member/garbage/friends
/member/friends/friends
These should both return true, however only the first one does. In the first case because "garbage" does not match with another other possible paths but there is an option for a wildcard at this point it will skip it and move on, then it sees "friends" and it knows it's a match. However, my second case does not work because it sees friends and goes down a different path in my trie, not the wildcard path. Because there is a valid path with "friends" in this position it thinks it will be that. Then it sees "friends" again but from this point in the trie there are no valid paths with "friends" so it returns false.
My question is, how can I get it to recognize the other valid path even when it goes down the wrong branch in the trie. My search code and example trie diagram is below.
The search algorithm for my trie is as follows:
private TrieNode searchNode(String input) {
Map<String, TrieNode> children = root.children;
TrieNode t = null;
// break up input into individual tokens
String[] tokenizedLine = input.split("/");
for(int i = 0; i < tokenizedLine.length; i++){
String current = tokenizedLine[i];
if(children.containsKey(current)) {
t = children.get(current);
children = t.children;
}else if(children.containsKey("X")){
t = children.get("X");
children = t.children;
}else{
return null;
}
}
return t;
}
An image of the trie that would be built with my sample path set:
When I input /member/friends/friends my algorithm is going down the highlighted path and stopping because it does not see another "friends" after, but how can I get it to recognize the first "friends" as a wildcard value instead, so then it will continue and see the second "friends" after the wildcard?
Thanks for any help!
Figured it out. I implemented some backtracking to keep track of the last node where it saw two possible paths. If it finds a dead end on one path it will go back to the last time it saw two possible paths and try the other. New Algorithm looks like this:
private TrieNode searchNode(String input) {
Map<String, TrieNode> children = root.children;
TrieNode t = null;
// Variables for backtrack function
TrieNode alternativeWildcardNode = null;
int wildcardIndex = 0;
Map<String, TrieNode> wildcardChildren = root.children;
// break up input into individual tokens
String[] tokenizedLine = input.split("/");
for(int i = 0; i < tokenizedLine.length; i++){
String current = tokenizedLine[i];
//System.out.println(current);
//System.out.println(Integer.toString(i));
if(children.containsKey(current) && children.containsKey("X")) {
// store current variable state in case we need to back track here
alternativeWildcardNode = children.get("X");
wildcardIndex = i;
wildcardChildren = alternativeWildcardNode.children;
t = children.get(current);
children = t.children;
}else if(children.containsKey(current)) {
t = children.get(current);
children = t.children;
}else if(children.containsKey("X")){
t = children.get("X");
children = t.children;
}else if(alternativeWildcardNode != null){
// if we've reached a branch with no match, but had a possible wildcard previously
// call reset state to the wildcard option instead of static
t = alternativeWildcardNode;
alternativeWildcardNode = null;
i = wildcardIndex;
children = wildcardChildren;
}else{
return null;
}
}
return t;
}

Difference between one pass (scan) and two pass(scan)

I had an Interview, a day before.
The Interviewer told me to , " Write a program to add a node at the end of a linked list ".
I had given him a solution. but he told me to implement it in one pass (one scan).
Can Anybody explain me, whats the meaning of one pass, and how to find the program written is in one pass or two pass?
Here is my code
public void atLast(int new_data)
{
Node new_node=new Node(new_data);
if(head==null)
{
head=new Node(new_data);
return;
}
new_node.next=null;
Node last=head;
while(last.next!=null)
{
last=last.next;
}
last.next=new_node;
return;
}
If that is the code you gave the interviewer must have misread it because it is a single pass.
In your case a "pass" would be your while loop. It could also be done with recursion, for, or any other type of loop that goes through the elements in the array (or other form of a list of items).
In your code you run through the list of Node and insert the element at the end. This is done in one loop making it a single pass.
Now to look at a case with two passes. Say for example you were asked to remove the element with the largest value and wrote something similar to this:
int index = 0;
int count = 0;
int max = 0;
while(temp_node != null)
{
if(temp_node.data > max)
{
index = count;
max = temp_node.data;
}
count++;
temp_node = temp_node.next;
}
for(int i = 0; i < count; i++)
{
if(i == index)
{
//Functionality to remove node.
}
}
The first pass (while) detects the Node which has the maximum value. The second pass (for) removes this Node by looping through all the elements again until the correct one is found.
I'd imagine "two passes" here means that you iterated through the whole list twice in your code. You shouldn't need to do that to add a new node.

find an object which has at least 1 parameter(out of three)that matches with corresponding parameter of each object from array

I'm creating a matching puzzle game, and I'm stuck in creating logic for this function.
Node is a class that has 3 parameters:
{
int a;
int b;
int c;
}
then if I have 2 node objects, say n1 and n2 and
(n1 == n2) if (n1.a == n2.a || n1.b == n2.b || n1.c == n2.c)
so if:
n1.a=6, n1.b=4, n1.c=3
and:
n2.a=4, n2.b=4, n2.c=5.
here ( n1 == n2 ) or n1 connects with n2 because ( n1.b == n2.b ).
The problem: I need to write logic for the function that accepts an array of node objects, and it should return a node object that can connect with all the nodes in the array. If a connecting node is impossible, it should return a null value. So the node returned should have at least 1 parameter in common with every object of the array.
I'm using ActionScript 3 but just need the logic part in either AS3 or pseudo-code.
You need to have a set of possible points that satisfy this condition, and filter it out at each new point added to the list. First you will have to spawn many "any-any" points, these must be differentiated from normal. You start the algorithm with one "any,any,any" point, then whenever a point (a,b,c) is added, you check the list of existing points, and drop any that are not compliant with "a,b,c", and a point with "any" is now axis-locked to either of the axes, meaning the first step makes "a,any,any","any,b,any","any,any,c" set of points in the list. This continues until either all the list is processed, or there are no points left in the list.
function allconnected(nodes:Vector.<Node>):Node {
var list:Array=[];
list.push({a:null,b:null,c:null}); // "any,any,any" initial object
for (var i:int=nodes.length-1;i>=0;i--) {
var node:Node=nodes[i]; // current node
if (list.length==0) return null; // no nodes match
for (var j:int=list.length-1;j>=0;j--) {
var o:Object=list.splice(j,1)[0]; // get the element out of the array
var pushed:Boolean=false;
if (o.a!==null) if (!pushed && (o.a==node.a)) {
list.push(o);
pushed=true;
}
if (o.b!==null) if (!pushed && (o.b==node.b)) {
list.push(o);
pushed=true;
}
if (o.c!==null) if (!pushed && (o.c==node.c)) {
list.push(o);
pushed=true;
}
// if this point connects by either side, and the side is defined, push it back
if (o.a===null) list.push({a:node.a,b:o.b,c:o.c});
if (o.b===null) list.push({a:o.a,b:node.b,c:o.c});
if (o.c===null) list.push({a:o.a,b:o.b,c:node.c});
// and if any side is "any", push an axis-aligned object in the list
} // this way new object that are aligned with current node
// are put into the array in an already processed segment, so we won't hit
// an infinite loop
}
// okay if we are here, then there is something left in the array
var result:Node=new Node();
result.a=list[0].a; // 0 if null, this is pretty much OK
result.b=list[0].b;
result.c=list[0].c;
return result;
}
This code has been written on-the-fly, and there might be errors inside, so don't blindly copy and paste, please.

Generating immutable cyclic data structures

Suppose I have this simple class:
public class Pair {
public readonly object first;
public readonly object second;
public Pair(object first, object second) {
this.first = first;
this.second = second;
}
}
It would be impossible to generate a cyclic graph of pairs.
How would you create a similar class, that is still immutable, but can be used somehow to generate cyclic graphs?
There are zillions of ways to represent graph structures. One such way is with a matrix. each row and column is indexed by the vertex, and each cell in the matrix represents a directed (possibly weighted) edge. A simple, cyclic graph, with 0's as no connecting edge and 1 with a connecting edge would just be like so:
| 0 1 |
| 1 0 |
As with many immutable structures, the way you construct them is by returning new structures based on the desired relationship of given matrices. for instance, if we wanted to take the above graph and add an edge on the first vertex back onto itself, the matrix representing that is just.
| 1 0 |
| 0 0 |
and to combine that with the other matrix, we just add them together.
| 0 1 | + | 1 0 | == | 1 1 |
| 1 0 | | 0 0 | | 1 0 |
Of course, there are many ways to represent matrices, with different tradeoffs for speed, space, and certain other operations, but that's a different question.
I don't think this is possible with a strictly immutable class of the type you proposed. The only thing I can think of is to add a property with a setter that check whether or not a field is null, and allows it to be set if it is. In this way you could leave the first field in the first object null, and once you've created the last object in the cycle set that field appropriately to close the loop. Once it's set, it is no longer null, and the setter would no longer allow it to be changed. It would still be possible for the field to be changed by code internal to the class, of course, but it would be essentially immutable from the outside.
Something like this (C#):
public class Pair {
private object first;
private object second;
public Pair(object first, object second) {
this.first = first;
this.second = second;
}
public object First {
get { return first; }
set
{
if (first == null)
{
first = value;
}
}
}
// and a similar property for second
}
I would take a functional approach, passing a continuation into the ctor. Alternately, it could take a sequence of similar elements instead (think IEnumerable as an argument).

Resources