Inside the class Test, there must be a public method getLinkedList and it shall receive nothing, but answer with a Node object.
You must create the Node class inside the Test class and it must be public. The Node class must have two instance variables. One that holds numbers and have the name TAL and one that holds a Node object and have the name NEXT.
Calling the getLinkedList the first time, it must answer with a Node object that has the TAL=1 and the NEXT=null
Calling the getLinkedList the second time, it must answer with a Node object that has the TAL=2 and the NEXT points to a Node with the TAL=1. This means that the first Node is placed last in the list and the newest Node is always at the front and its TAL value is the same as the numbers of Nodes in the list.
This is what I've done so far. Don't give me the answer direct please.
public Node getLinkedList()
{
Node n = new Node();
n.TAL = 1;
n.NEXT = null;
Node n1 = new Node();
n1.TAL = 2;
n.NEXT.TAL = n.TAL;
}
public class Node
{
public int TAL;
public Node NEXT;
}
Alright without giving you too much, here's what you need to do with your get linked list function.
public Node GetLinkedList()
{
//Check if your linked list is empty
//If yes return your TAL = 1 node
//If no create a new node with new TAL and return that
}
This should get you pointed in the right direction at least. You need some conditional logic in there
Related
This is a leetcode problem.
I saw the solution however while trying to use my own logic, I cannot iterate over to the next node.
public ListNode AddTwoNumbers(ListNode l1, ListNode l2)
{
try
{
string l1NodeData = null;
string l2NodeData = null;
do
{
l1NodeData = l1NodeData + l1.val;
l1 = l1.next;
} while (l1 != null);
do
{
l2NodeData = l2NodeData + l2.val;
l2 = l2.next;
} while (l2 != null);
int sum = Convert.ToInt32(l1NodeData) + Convert.ToInt32(l2NodeData);
var sumInChar = sum.ToString().ToArray();
ListNode dummyhead = new ListNode(0);
ListNode ans = dummyhead;
for (int i = sumInChar.Length - 1; i > 0; i--)
{
ans.val = Convert.ToInt32(sumInChar[i].ToString());
ListNode tempListNode = new ListNode(Convert.ToInt32(sumInChar[i - 1].ToString()));
ans.next = tempListNode;
ans = ans.next;
//here(ans = ans.next) after assigning the next node, the data of the current node is getting overridden.
}
return ans;
}
catch (Exception ex)
{
Console.WriteLine(ex);
throw;
}
}
In the above solution where I am assigning ans = ans.next, there the current node is overridden with the next node, however, I just want to move to the next node in order to iterate.
Could someone please help me on this?
In the above solution where I am assigning ans = ans.next, there the current node is overridden with the next node, however, I just want to move to the next node in order to iterate.
The assignment is to a variable. That never mutates your linked list. This way of assigning to a variable is exactly what you need to traverse a linked list. It does not modify it. In order to mutate it, you will always need to assign to a member (property) of a node, like its next property.
In the code comments you wrote:
the data of the current node is getting overridden.
No, it looks like that because you return the reference to the last node that was created in the loop. Instead you should return dummyHead.next; This way you return the first node that was created in the loop.
In comments you wrote:
...I have not made any assignment to dummyhead right, then how does data reside in that variable?
You have referenced ans to the same node as dummyHead, and you did assign to ans.next, which in the first iteration of the loop is synonymous to dummyHead.next. With those assignments to ans.next the nodes get linked to eachother.
Note that dummyHead is an extra node that is created to ease the code in the loop -- not having to make a special case for creating the real head node. After the loop that dummyHead is then ignored (it served its purpose), and the real head (that is sitting right after it) is returned.
This question already has answers here:
Can static method access non-static instance variable?
(5 answers)
Closed 2 years ago.
Guys when I try to create an instance variable to create an istance of class (object) out of Main method it doesn't work. I couldn't understand why ? I have really searched on the Internet many times.
For example
This works
This doesn't work
As I learned before keywords "int", "string" etc. are kind of class. I can create a instance variable by using those keywords (i.e class) out of Main() method.
But Why I cant create an istance variable by using class name out of Main() method.
My second question is I am really wondering why do I need a instance variable by using class name.
I mean when I create an istance variable by using "string", "int" etc. keywords. I can picture thpe of that variable. But when ı created a instance variable by using class name I can't picture anything in my mind.
Thanks advance for your interest
For your second question, in C#, an instance of a class is always a reference variable. (I recommend you to read more about it in the internet). Therefore, in the example:
class Student
{
Student st1;
}
str1 can reference to an area in the RAM. You can picture it as an arrow to a rectangle. The arrow is the variable that reference to the rectangle, which is the place on the RAM. By creating an instance of a class inside of the class itself, we actually create an arrow to a new rectangle that has also an arrow that can reference to a rectangle too, and so on.
It is useful, for example, to create a list of nodes. Each node references to another node, like the following:
class Node
{
public int number;
public Node next; // Here we create a new arrow to a new rectangle, which has an arrow too
}
And in the Main method:
Node first = new Node();
first.number = 1;
Node second = new Node();
second.number = 2;
first.next = second; // Here we "match" the arrow to a rectangle. The arrow is "first.next", and the rectangle is "second".
Node third = new Node();
third.number = 3;
second.next = third;
// We have a list: 1 -> 2 -> 3 -> null
// The end of the list is null, becuase third.next references to null (it references to no "rectangle")
We can do it in a different way:
Node first = new Node();
first.number = 1;
first.next = new Node();
first.next.number = 2;
first.next.next = new Node();
first.next.next.number = 3;
// In this way, we have only the "head" of the list ("first"), but we can get any node that in the list by typing "first.next. ....... .next"
// We can also iterate over the list:
Node p = first;
while (p != null) // while we are not in the end of the list
{
// Do something, like "Console.WriteLine(p.number);" or "p.number++;"
p = p.next; // We go to the next node
}
It is useful, because this list has no limited length and we can add nodes and remove nodes easily.
For example:
public class Program
{
public static void Main(string[] args)
{
Node first = new Node();
int counter = 0;
first.number = counter;
counter++;
// Inialize a list of 10 nodes:
Node p = first; // We don't want to lost the "head" of our list, "first"
while (counter < 10)
{
p.next = new Node(); // We create a new node
p.next.number = counter; // And we initialize it
counter++;
p = p.next; // We go to the next node
}
// Now we print all the number in our list:
p = first; // We don't want to lost the "head" of our list, "first"
while (p != null)
{
Console.WriteLine(p.number);
p = p.next; // We go to the next node
}
}
}
Output:
0
1
2
3
4
5
6
7
8
9
Hope it will be helpful!
Hello I currently have a TreeView with the following structure:
Root
Child
Root
Child
Root
Child
Child
RootN
ChildN
The TreeView structure can basically have NRootNodes - NChildren and the NRootNodes can have NRoots and NChildren so basically just like Windows Explorer Window.
My current issue that I have is that I have to get all the Parents or Root, in this case Roots / RootN and then I have to Remove all of their Child Nodes, in this case Child / ChildN. In the end I have to have only the Parent Nodes and then Clone them so I can move them to a different location within the TreeView.
RootNodes have a unique Tag - Folder and ChildNodes have another unique Tag - Calculations, as I have said earlier, I have to get rid of all Calculations in the Selected Node so only the Structure of that Selected Node will Remain.
Basically in the end I have to have something like this:
Root
Root
Root
Root
Root
I have a recursive method that "scans" the SelectedNode and gets all the Parents:
public List<TreeNode> CollectParentNodes(TreeNodeCollection parentCollection, List<TreeNode> collectedNodes)
{
foreach (TreeNode node in parentCollection)
{
if (!collectedNodes.Contains(node.Parent))
{
collectedNodes.Add(node.Parent);
parentNodeAdded = true;
}
if (node.Level != 0 && node.Tag.ToString() != Enumerations.NodeType.Calculation.ToString())
collectedNodes.Add(node);
if (node.Nodes.Count > 0)
CollectParentNodes(node.Nodes, collectedNodes);
}
parentNodeAdded = false;
return collectedNodes;
}
In the end I have a List that will hold all the Parents but the problem I'm facing is that that Parents also contain their descendents, in this case the Calculations
I have searched Google and StackOverFlow but I could not find anything of help, I appologize in advance if this has already been answered.
Thank you.
You can create an extension method GetAllNodes for TreeView that return List
Remember using using System.Linq; at top of your code
public static class Extensions
{
public static List<TreeNode> GetAllNodes(this TreeView tree)
{
var firstLevelNodes = tree.Nodes.Cast<TreeNode>();
return firstLevelNodes.SelectMany(x => GetNodes(x)).Concat(firstLevelNodes).ToList();
}
private static IEnumerable<TreeNode> GetNodes(TreeNode node)
{
var nodes = node.Nodes.Cast<TreeNode>();
return nodes.SelectMany(x => GetNodes(x)).Concat(nodes);
}
}
And the usage will be:
var result = this.treeView1.GetAllNodes().Where(x => x.Tag == "FOLDER").ToList();
Remember to add namespace of your extensions class at top of your code wherever you want to use it.
As an example you can set All nodes with tag of Folder to be in Red forecolor:
var result = this.treeView1.GetAllNodes().Where(x => (x.Tag as string) == "FOLDER").ToList();
result.ForEach(x => x.ForeColor = Color.Red);
And here is an Screenshot
This will create a new tree with the selected node as root and which child nodes consists only of nodes that are tagged "Folder".
You need to create a copy constructor (or extension method) to deep copy the node to prevent the manipulation on the node objects to impact your original tree source:
public TreeNode CollectFolderChildNodes(TreeNode selectedNode)
{
if (selectedNode.Tag == "Calculation")
return null;
// Get all the children that are tagged as folder
var childRootNodes = selectedNode.Children.Where((childNode) => childNode.Tag == "Folder";
// Clone root node using a copy constructor
var newRoot = new TreeNode(selectedNode);
newRoot.Children.Clear();
foreach (var childNode in childRootNodes)
{
// Iterate over all children and add them to the new tree
if (childNode.Children.Any())
{
// Repeat steps for the children of the current child.
// Recursion stops when the leaf is reached
newRoot.Children.Add(CollectFolderChildNodes(childNode));
}
else
{
// The current child item is leaf (no children)
newRoot.Children.Add(new TreeNode(childNode));
}
}
return newRoot;
}
I think this should do it, but I didn't tested it. But maybe at least the idea behind it is clear.
But as I mentioned before, maybe it's better to traverse the tree (using same ItemsSource) and set a property (e.g. IsHidingCalculations) to true so that only the folders will show up. You would need to implement an ItemsStyle and use a trigger that sets the items Visibility to Collapsed when your IsHidingCalculations evaluates to true.
To clone a node without its children you can create an extension method like this:
public static TreeNode CloneWithoutChildren(this TreeNode node)
{
return new TreeNode(node.Text, node.ImageIndex, node.SelectedImageIndex)
{
Name = node.Name,
ToolTipText = node.ToolTipText,
Tag = node.Tag,
Checked = node.Checked
}
}
and then:
collectedNodes.Add(node.CloneWithoutChildren());
I want to build a tree structure like this:
root Id 1
child id 2
grandChild id 3
Code sample below. If I use GetChildrenNodesCorrect(), I get the correct result. But when GetChildrenNodesWrong() is used, it returns below:
root Id 1
child id 2
Null
I know that ToList() is not deferred execution, and returns result immediatelly. Could anyone explain this?
public class ToListTest
{
public static void Entry()
{
var toListTest = new ToListTest();
toListTest.Test();
}
public void Test()
{
List<Node> newsList = new List<Node>
{
new Node{Id = 1, ParentId = 0},
new Node{Id = 2, ParentId = 1},
new Node{Id = 3, ParentId = 2}
};
var root = BuildUpTree(newsList);
}
private TreeNode BuildUpTree(List<Node> newsList)
{
var root = new TreeNode { currentNode = newsList.First(n => n.ParentId == 0) };
BuildUpTreeChildrenNodes(newsList, root);
return root;
}
private void BuildUpTreeChildrenNodes(List<Node> newsList, TreeNode currentTreeNode)
{
currentTreeNode.Children = GetChildrenNodesWrong(newsList, currentTreeNode);
foreach (var node in currentTreeNode.Children)
{
BuildUpTreeChildrenNodes(newsList, node);
}
}
private IEnumerable<TreeNode> GetChildrenNodesWrong(List<Node> newsList, TreeNode cuurentNode)
{
return newsList.Where(n => n.ParentId == cuurentNode.currentNode.Id)
.Select(n => new TreeNode
{
currentNode = n
});
}
private IEnumerable<TreeNode> GetChildrenNodesCorrect(List<Node> newsList, TreeNode cuurentNode)
{
return GetChildrenNodesWrong(newsList, cuurentNode).ToList();
}
public class TreeNode
{
public Node currentNode { get; set; }
public IEnumerable<TreeNode> Children { get; set; }
}
public class Node
{
public int Id { get; set; }
public int ParentId { get; set; }
}
}
Update
In debug, when using GetChildrenNodesWrong(), root has both child and grandchild before the method returns. After the method returns, root has only child, and grandchild is null.
Update 2
IMO, the problem might not be related to clean code. But anyone is welcome to show more intuitive code.
Every time the IEnumerable is evaluated the Linq query is re-executed. So, when you're computing the tree, it is allocating space for nodes but not assigning them to any permanent variable. This means that in the foreach loop in BuildUpTreeChildrenNodes, you are not calling the recursive function on the instance of the node you want. Instead, you're calling it on a re-instantiated version of the node that has been created by the foreach loop (which enumerates the IEnumerable). When you call ToList on the IEnumerable instead, then the foreach loop will return the elements of the list, which is in memory.
If you make root public static, and then debug your code, you'll see that when you call BuildUpTreeChildrenNodes, the node argument is not the instance of the node that you want. Even though it has the same ID and represents the same node in the graph, it is not actually connected in any way to the root node. Check:
root.Children.Any(n => n.Id == node.Id) //true
root.Children.Contains(node) //false
The simplest way to see your problem is here:
//Create a singleton Node list:
var nodeSingleton= Enumerable.Range(0, 1).Select(x => new Node { Id = x });
Console.Write(nodeSingleton.Single() == nodeSingleton.Single());
You might expect this to return true, but in fact it will be false - both times the Single Linq method is called, the deferred execution of the singleton variable is re-evaluated, and returns a different instance of the Node class.
If you call ToList on the singleton, however, then you get the list in memory and the Single method will return the same instance of the Node.
More broadly, I think the problem with this code is that it mixes up imperative and functional code too much. It is strange that so many of the methods are void and then the GetChildrenNodesWrong method is not. I think you should pick a style and stick with it, since switching paradigms can be confusing.
I'm not entirely sure what you're asking. All LINQ queries have deferred execution, when you call ToList() you're simply forcing the query to execute. I think the main problem is in your where clause. Only two objects satisfy the condition so the IEnumerable returned by your LINQ query should only have 2 objects.
It's not doing what you expect because the LINQ query in GetChildrenNodesWrong is producing an "off by one" error. Here is basically what happens;
1) we feed it root for n = root nothing happens. We move to the next node.
2) n.Id = 1, the where condition is met by node 2 as it's parentId is 1. We allocate a new node, point current to node 2
3) We get to the third node now. n.ParentId = 2 and current.Id = 2. We have a match so we allocated another node and point current to node 3.
4) we're at the end of the list. Grand child is never allocated because we're off by one.
Basically you iterate x time where x is the length of the list but because current = n on the first iteration you don't allocate a node so you end up with x -1 nodes when you're expecting x.
I have a graph, each node have 4 child nodes. I wrote a algorithm to generate a random path from a begin node to an end node. At each node, it chooses a random next node. Visited node can be revisited.
the code is like the following:
public List<Node> GetPath(Node begin, Node end)
{
var nodes = new List<Node>();
var node = begin;
while (node != end)
{
nodes.Add(node);
var next = node.Children[new Random().Next(4)];
node = next;
}
nodes.Add(end);
return nodes;
}
But sometimes, the Random does not work as expected. The "new Random().Next(4)" keeps generating 0. So it is always the first child node get chose and a very long repeat sequence like node1->node2->node1->node2... is generated and eventually an out of memory exception happens.
Is there a way to make the Random class works correctly?
The reason is because Random is initialized based on the current time (there is no true random in computers... only psuedo-random). The while loop iterates too quickly, and the system time has not registered a change. So you're re-initializing a new Random object that starts with the same value.
Try creating one Random object that is reused throughout the method:
public List<Node> GetPath(Node begin, Node end)
{
var nodes = new List<Node>();
var node = begin;
Random r = new Random();
while (node != end)
{
nodes.Add(node);
var next = node.Children[r.Next(4)];
node = next;
}
nodes.Add(end);
return nodes;
}
Initialize Random instance outside loop, e.g.:
public List<Node> GetPath(Node begin, Node end)
{
var nodes = new List<Node>();
var node = begin;
var random = new Random();
while (node != end)
{
nodes.Add(node);
var next = node.Children[random.Next(4)];
node = next;
}
nodes.Add(end);
return nodes;
}
You mention that the method is being called upon in multiple threads. A solution is to have one random number generartor per thread that is seeded by a static rng.
I've also removed the constant 4 and changed it to node.Children.Count.
static Random seed = new Random();
[ThreadLocal] static Random rng;
public List<Node> GetPath(Node begin, Node end)
{
var nodes = new List<Node>();
var node = begin;
if (rng == null)
rng = new Random(seed.Next());
while (node != end)
{
nodes.Add(node);
var next = node.Children[rng.Next(node.Children.Count)];
node = next;
}
nodes.Add(end);
return nodes;
}
There are a few things working against you here. The first is that you're expecting a different number every time you ask for one, but that's not what this class does nor is it the definition of random. So, this class is in fact working correctly.
Definition of Random
Made, done, happening, or chosen without method or conscious decision: "a random sample of 100 households".
Governed by or involving equal chances for each item.
Now, this class does its best at giving each option an equal opportunity at being chosen. So, when you think of random make sure you're putting into context the definition of the term. However, remember that this class does not work like the human mind.
Now, to address the fact that you're getting zero very frequently, it's happening for two reasons. First, you are creating a new Random class in every iteration. But more importantly, your range is too small because you're expecting it to give you a different number every time on a range of only 4 options, and since it's pseudo-random just as MSDN states you're getting the same answer frequently.
I realize the reason you're only giving it 4 options, but I think you might need to reconsider the type of functionality you're looking for because it would probably lead to less frustration.