I've an issue to ask you guys.
I have a class shown below:
public class Node
{
public int Kova1; // Kova 1
public int Kova2; // Kova 2
public int Kova3; // Kova 3
public int ActionNo; // Yapılan İşlem
public Node(int kova1, int kova2, int kova3, int actionNumber)
{
Kova1 = kova1;
Kova2 = kova2;
Kova3 = kova3;
ActionNo = actionNumber;
}
public Node(int kova1, int kova2, int kova3)
{
Kova1 = kova1;
Kova2 = kova2;
Kova3 = kova3;
}
public Node()
{
}
public Node AnneNode;
}
And these functions:
public void CocukNodeOlustur(LinkedList<Node> Acik, LinkedList<Node> Kapali, Node temp)
{
Node cocukState;
Node temp2 = temp;
for (int i = 0; i < 12; i++)
{
cocukState = YeniStateOlustur(temp, i);
if ((ActionKontrol(cocukState)) && (GoalBulundu(Acik, Kapali, cocukState)) &&
((cocukState.Kova1 != temp2.Kova1) && (cocukState.Kova2 != temp2.Kova2) && (cocukState.Kova3 != temp2.Kova3)))
{
cocukState.AnneNode = temp;
Acik.AddFirst(temp);
}
}
}
public Node YeniStateOlustur(Node s, int j)
{
int tempKova1, tempKova2, tempKova3;
Node yeniCocuk = new Node();
yeniCocuk = s;
yeniCocuk.ActionNo = j;
// Gelen numaraya göre uygulanan işlemin seçimi yapılıyor.
switch (j)
{
case 0:
{
yeniCocuk.Kova1 += (3 - yeniCocuk.Kova1);
yeniCocuk.Kova2 += 0;
yeniCocuk.Kova3 += 0;
}
break;
case 1:
{
yeniCocuk.Kova1 += 0;
yeniCocuk.Kova2 += (5 - yeniCocuk.Kova2);
yeniCocuk.Kova3 += 0;
}
break;
}
return yeniCocuk;
}
In the main function
Node temp = new Node();
while (!(Acik.Count == 0))
{
p.CocukNodeOlustur(Acik, Kapali, temp);
Kapali.AddLast(temp);
}
So When I debug my program, I see that Whenever the code jumps to the YeniStateOlustur() function, all the Node instance's in program is affected by the changes in YeniStateOlustur(). It seems the instance in the function overwrite all instances of Node class.
I don't understand why it happens?
How can I overcome this?
My best regards and sory for the long post.
The problem is that all of the nodes are the same instance. Your sample code includes "new Node()" only twice, and in the second case (inside the method YeniStateOlustur), the new instance is immediately discarded. That function therefore returns the same node that was passed to it:
public Node YeniStateOlustur(Node s, int j)
{
int tempKova1, tempKova2, tempKova3;
Node yeniCocuk = new Node();
yeniCocuk = s;
//...
return yeniCocuk;
}
In the method CocukNodeOlustur, all node variables point to the same Node:
public void CocukNodeOlustur(LinkedList<Node> Acik, LinkedList<Node> Kapali, Node temp)
{
// here, temp == temp
Node cocukState;
// now, temp == temp and cocukState is uninitialized.
Node temp2 = temp;
// now, temp == temp, temp2 == temp, and cocukState is uninitialized.
for (int i = 0; i < 12; i++)
{
cocukState = YeniStateOlustur(temp, i);
// now, temp == temp, temp2 == temp, and cocukState == temp
if ((ActionKontrol(cocukState)) && (GoalBulundu(Acik, Kapali, cocukState)) &&
((cocukState.Kova1 != temp2.Kova1) && (cocukState.Kova2 != temp2.Kova2) && (cocukState.Kova3 != temp2.Kova3)))
{
cocukState.AnneNode = temp;
Acik.AddFirst(temp);
}
}
}
Your code seems to assume that Node is a value type (struct), but it is obviously a reference type (class). If you're unsure about the difference, you should take a step back and do some reading and experimentation.
A quick fix might be to change the declaration of Node to a struct, but I would recommend against that. Programming with structs can be very tricky, and that would be especially true if your understanding of the differences between structs and classes is shaky.
Related
public void Push(Node newNode)
{
while (true)
{
Node tmp = this.head;
newNode.next = tmp;
if (Interlocked.CompareExchange(ref this.head, newNode, tmp) == tmp)
{
break;
}
}
}
public Node Pop()
{
Node pop=null;
while (this.head != null)
{
pop = this.head;
var oldcount = this.popcount;
var newcount = oldcount + 1;
if (Interlocked.CompareExchange(ref this.popcount, newcount, oldcount) == oldcount)
{
pop = Interlocked.CompareExchange(ref head, head.next, head);
break;
}
pop = null;
}
return pop;
}
//---------------------------------------------------------
while (count < 10000) // 4 thread run this code
{
for (int i = 0; i < 2; i++)
{
Node temp;
if (freelist.head != null)
{
temp = freelist.Pop();
headlist.Push(temp);
}
}
for (int j = 0; j < 1; j++)
{
Node temp;
if (headlist.head != null)
{
temp = headlist.Pop();
freelist.Push(temp);
}
}
count++;
Console.WriteLine(count);
}
I'm trying to implement lock free linkedlist.
I add popcount to avoid aba problem.
And I implement Push and Pop using CAS.
When I run this code, It is not working as I think.
class Node
{
public int data;
public Node next;
public Node(int data)
{
this.data = data;
}
}
When I run code, a Node.next points itself.
For example, Node.data = 99720 and Node.next = Node So, When I go to Node.next It is still 99720 Node.
Can't figure out why it happen...
It looks like you are trying to build a lock-free stack. I'm not sure what (pseudo-) code you used as basis for your implementation, but your attempt to solve the ABA problem with popcount cannot work. When you are using a version tag to prevent ABA, it has to be combined with the pointer, i.e., the pointer and the tag have to be updated in a single atomic operation. Java provides AtomicStampedReference for exactly this purpose, but unfortunately .NET does not provide anything similar.
However, since you are working with .NET you have the luxury of a garbage collector, so you don't really need to worry about the ABA problem as long as you don't reuse your nodes.
BTW: your pop function is missing a loop.
I was studying search algorithms and wanted to solve the missionaries and cannibals problem in order to practice. However, my code never provides a solution. At first, I thought this was because I had recurring states, causing an infinite loop, so I added a state history to make sure states weren't being repeated. However, this still has not worked.
Below is the code I have written. I am using vectors to represent the states of the missionaries, cannibals and the boat and the children of the nodes get added if they pass a check that checks if the move is within the range (0,0,0) and (3,3,1).
I have tried stepping through the code but since the tree is fairly large I can only keep track of so many things, so I have a hard time seeing the fault in my code.
This was written in Visual Studio as a console program.
Vector3 class
public class Vector3
{
public int m;
public int c;
public int b;
public Vector3(int M, int C, int B)
{
m = M;
c = C;
b = B;
}
public override bool Equals(System.Object obj)
{
if (obj == null)
return false;
Vector3 p = obj as Vector3;
if ((System.Object)p == null)
return false;
return (m == p.m) && (c == p.c) && (b == p.b);
}
}
Node class
public class Node
{
public Vector3 State;
public Node(Vector3 st)
{
State = st;
}
}
My Program.cs
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.DFS(new Node(new Vector3(3, 3, 1)));
Console.ReadKey();
}
List<Vector3> History = new List<Vector3>();
Vector3[] Operators = new Vector3[]
{
new Vector3(1,0,1),
new Vector3(2,0,1),
new Vector3(0,1,1),
new Vector3(0,2,1),
new Vector3(1,1,1),
};
public bool TryMove(Vector3 current, Vector3 toApply, bool substract)
{
if (substract)
{
if (current.c - toApply.c < 0 || current.m - toApply.m < 0 || current.b - toApply.b < 0 || (current.c - toApply.c) > (current.m - toApply.m))
{
return false;
}
else return true;
}
else
{
if (current.c + toApply.c > 3 || current.m + toApply.m > 3 || current.b + toApply.b > 1 || (current.c + toApply.c) > (current.m + toApply.m))
{
return false;
}
else return true;
}
}
public void DFS(Node n)
{
Stack<Node> stack = new Stack<Node>();
stack.Push(n);
while (stack.Count > 0)
{
Node curNode = stack.Pop();
if (History.Contains(curNode.State))
{
}
else
{
History.Add(curNode.State);
if (curNode.State == new Vector3(0, 0, 0))
{
Console.WriteLine("Solution found.");
return;
}
else
{
if (curNode.State.b == 0) //Boat is across the river
{
for (int x = 0; x < 5; x++)
{
if (TryMove(curNode.State, Operators[x], false))
{
stack.Push(new Node(new Vector3(curNode.State.m + Operators[x].m, curNode.State.c + Operators[x].c, curNode.State.b + Operators[x].b)));
}
}
}
else //Boat == 1
{
for (int x = 0; x < 5; x++)
{
if (TryMove(curNode.State, Operators[x], true))
{
stack.Push(new Node(new Vector3(curNode.State.m - Operators[x].m, curNode.State.c - Operators[x].c, curNode.State.b - Operators[x].b)));
}
}
}
}
}
}
Console.WriteLine("No solution found.");
return;
}
}
My code keeps hitting the 'No solution found' block. When I remove the history I keep infinite looping between states (3,3,1) and (2,2,1) and get an OutOfMemoryException at the 2 gigabyte mark, so I'm not even sure about keeping track of history anymore.
What steps should I take in order to implement the DFS in the context of the problem correctly, given the code I provided above?
Your algorithm is fine. The problem is that you used == operator in curNode.State == new Vector3(0, 0, 0); line. In C#, by default, == compares objects by reference, so this condition will always return false. Either use node.State.Equals(new Vector3(0, 0, 0)) or override == operator to use your Equals method.
See MSDN Guidelines on custom comparison in C#.
I'm working on a hacker rank problem and I believe my solution is correct. However, most of my test cases are being timed out. Could some one suggest how to improve the efficiency of my code?
The important part of the code starts at the "Trie Class".
The exact question can be found here: https://www.hackerrank.com/challenges/contacts
using System;
using System.Collections.Generic;
using System.IO;
class Solution
{
static void Main(String[] args)
{
int N = Int32.Parse(Console.ReadLine());
string[,] argList = new string[N, 2];
for (int i = 0; i < N; i++)
{
string[] s = Console.ReadLine().Split();
argList[i, 0] = s[0];
argList[i, 1] = s[1];
}
Trie trie = new Trie();
for (int i = 0; i < N; i++)
{
switch (argList[i, 0])
{
case "add":
trie.add(argList[i, 1]);
break;
case "find":
Console.WriteLine(trie.find(argList[i, 1]));
break;
default:
break;
}
}
}
}
class Trie
{
Trie[] trieArray = new Trie[26];
private int findCount = 0;
private bool data = false;
private char name;
public void add(string s)
{
s = s.ToLower();
add(s, this);
}
private void add(string s, Trie t)
{
char first = Char.Parse(s.Substring(0, 1));
int index = first - 'a';
if(t.trieArray[index] == null)
{
t.trieArray[index] = new Trie();
t.trieArray[index].name = first;
}
if (s.Length > 1)
{
add(s.Substring(1), t.trieArray[index]);
}
else
{
t.trieArray[index].data = true;
}
}
public int find(string s)
{
int ans;
s = s.ToLower();
find(s, this);
ans = findCount;
findCount = 0;
return ans;
}
private void find(string s, Trie t)
{
if (t == null)
{
return;
}
if (s.Length > 0)
{
char first = Char.Parse(s.Substring(0, 1));
int index = first - 'a';
find(s.Substring(1), t.trieArray[index]);
}
else
{
for(int i = 0; i < 26; i++)
{
if (t.trieArray[i] != null)
{
find("", t.trieArray[i]);
}
}
if (t.data == true)
{
findCount++;
}
}
}
}
EDIT: I did some suggestions in the comments but realized that I can't replace s.Substring(1) with s[0]... because I actually need s[1..n]. AND s[0] returns a char so I'm going to need to do .ToString on it anyways.
Also, to add a little more information. The idea is that it needs to count ALL names after a prefix for example.
Input: "He"
Trie Contains:
"Hello"
"Help"
"Heart"
"Ha"
"No"
Output: 3
I could just post a solution here that gives you 40 points but i guess this wont be any fun.
Make use of Enumerator<char> instead of any string operations
Count while adding values
any charachter minus 'a' makes a good arrayindex (gives you values between 0 and 25)
I think, this link must be very helpfull
There, you can find the good implementation of a trie data structure, but it's a java implementation. I implemented trie on c# with that great article one year ago, and i tried to find solution to an another hackerrank task too ) It was successful.
In my task, i had to a simply trie (i mean my alphabet equals 2) and only one method for adding new nodes:
public class Trie
{
//for integer representation in binary system 2^32
public static readonly int MaxLengthOfBits = 32;
//alphabet trie size
public static readonly int N = 2;
class Node
{
public Node[] next = new Node[Trie.N];
}
private Node _root;
}
public void AddValue(bool[] binaryNumber)
{
_root = AddValue(_root, binaryNumber, 0);
}
private Node AddValue(Node node, bool[] val, int d)
{
if (node == null) node = new Node();
//if least sagnificient bit has been added
//need return
if (d == val.Length)
{
return node;
}
// get 0 or 1 index of next array(length 2)
int index = Convert.ToInt32(val[d]);
node.next[index] = AddValue(node.next[index], val, ++d);
return node;
}
Code example:
using System;
public class Test {
public static void Main() {
int a = 0;
if(a++ == 0){
Console.WriteLine(a);
}
}
}
In this code the Console will write: 1. I can write this code in another way:
public static void Main() {
int a = 0;
if(a == 0){
a++;
Console.WriteLine(a);
}
}
These two examples work exactly the same (from what I know about postfix).
The problem is with this example coming from the Microsoft tutorials:
using System;
public class Document {
// Class allowing to view the document as an array of words:
public class WordCollection {
readonly Document document;
internal WordCollection (Document d){
document = d;
}
// Helper function -- search character array "text", starting
// at character "begin", for word number "wordCount". Returns
//false if there are less than wordCount words. Sets "start" and
//length to the position and length of the word within text
private bool GetWord(char[] text, int begin, int wordCount,
out int start, out int length) {
int end = text.Length;
int count = 0;
int inWord = -1;
start = length = 0;
for (int i = begin; i <= end; ++i){
bool isLetter = i < end && Char.IsLetterOrDigit(text[i]);
if (inWord >= 0) {
if (!isLetter) {
if (count++ == wordCount) {//PROBLEM IS HERE!!!!!!!!!!!!
start = inWord;
length = i - inWord;
return true;
}
inWord = -1;
}
} else {
if (isLetter) {
inWord = i;
}
}
}
return false;
}
//Indexer to get and set words of the containing document:
public string this[int index] {
get
{
int start, length;
if(GetWord(document.TextArray, 0, index, out start,
out length)) {
return new string(document.TextArray, start, length);
} else {
throw new IndexOutOfRangeException();
}
}
set {
int start, length;
if(GetWord(document.TextArray, 0, index, out start,
out length))
{
//Replace the word at start/length with
// the string "value"
if(length == value.Length){
Array.Copy(value.ToCharArray(), 0,
document.TextArray, start, length);
}
else {
char[] newText = new char[document.TextArray.Length +
value.Length - length];
Array.Copy(document.TextArray, 0, newText, 0, start);
Array.Copy(value.ToCharArray(), 0, newText, start, value.Length);
Array.Copy(document.TextArray, start + length, newText,
start + value.Length, document.TextArray.Length - start - length);
document.TextArray = newText;
}
} else {
throw new IndexOutOfRangeException();
}
}
}
public int Count {
get {
int count = 0, start = 0, length = 0;
while (GetWord(document.TextArray, start + length,
0, out start, out length)) {
++count;
}
return count;
}
}
}
// Class allowing the document to be viewed like an array
// of character
public class CharacterCollection {
readonly Document document;
internal CharacterCollection(Document d) {
document = d;
}
//Indexer to get and set character in the containing
//document
public char this[int index] {
get {
return document.TextArray[index];
}
set {
document.TextArray[index] = value;
}
}
//get the count of character in the containing document
public int Count {
get {
return document.TextArray.Length;
}
}
}
//Because the types of the fields have indexers,
//these fields appear as "indexed properties":
public WordCollection Words;
public readonly CharacterCollection Characters;
private char[] TextArray;
public Document(string initialText) {
TextArray = initialText.ToCharArray();
Words = new WordCollection(this);
Characters = new CharacterCollection(this);
}
public string Text {
get {
return new string(TextArray);
}
}
class Test {
static void Main() {
Document d = new Document(
"peter piper picked a peck of pickled peppers. How many pickled peppers did peter piper pick?"
);
//Change word "peter" to "penelope"
for(int i = 0; i < d.Words.Count; ++i){
if (d.Words[i] == "peter") {
d.Words[i] = "penelope";
}
}
for (int i = 0; i < d.Characters.Count; ++i) {
if (d.Characters[i] == 'p') {
d.Characters[i] = 'P';
}
}
Console.WriteLine(d.Text);
}
}
}
If I change the code marked above to this:
if (count == wordCount) {//PROBLEM IS HERE
start = inWord;
length = i - inWord;
count++;
return true;
}
I get an IndexOutOfRangeException, but I don't know why.
Your initial assumption is incorrect (that the two examples work exactly the same). In the following version, count is incremented regardless of whether or not it is equal to wordCount:
if (count++ == wordCount)
{
// Code omitted
}
In this version, count is ONLY incremented when it is equal to wordCount
if (count == wordCount)
{
// Other code omitted
count++;
}
EDIT
The reason this is causing you a failure is that, when you are searching for the second word (when wordCount is 1), the variable count will never equal wordCount (because it never gets incremented), and therefore the GetWord method returns false, which then triggers the else clause in your get method, which throws an IndexOutOfRangeException.
In your version of the code, count is only being incremented when count == wordCount; in the Microsoft version, it's being incremented whether the condition is met or not.
using System;
public class Test {
public static void Main() {
int a = 0;
if(a++ == 0){
Console.WriteLine(a);
}
}
}
Is not quite the same as:
public static void Main() {
int a = 0;
if(a == 0){
a++;
Console.WriteLine(a);
}
}
In the second case a++ is executed only if a == 0. In the first case a++ is executed every time we check the condition.
There is your mistake:
public static void Main() {
int a = 0;
if(a == 0){
a++;
Console.WriteLine(a);
}
}
It should be like this:
public static void Main() {
int a = 0;
if(a == 0){
a++;
Console.WriteLine(a);
}
else
a++;
}
a gets alwasy increased. This means, that in your code example count will get only increased when count == wordCount (In which case the method will return true anyway...). You basicly never increasing count.
public void HeightIterative()
{
int counter = 0;
int counter2 = 0;
TreeNode current=root;
if(current != null)
{
while(current.LeftNode!=null)
{
counter++;
current = current.LeftNode;
}
while(current.RightNode!=null)
{
counter2++;
current = current.RightNode;
}
}
int res = 1+Math.Max(counter, counter2);
Console.WriteLine("The Height Of Tree Is: "+res);
}
I wrote iterative method, to calculate height of tree. but in some cases its not working properly. As in case:
10
1
2
3
4
5
18
17
16
15
14
13
what's the problem. according to this sequence height of tree is 6 where as my code is showing 5.
You are using two loops, but each loop investigated only oneside of node, but each node in tree has two sides you should investigate it all. You can do it through recursion call.
private int GetLen(TreeNode node)
{
var result = 0;
if(node != null)
{
result = Math.Max(GetLen(node.LeftNode), GetLen(node.RightNode)) + 1;
}
return result;
}
public void HeightIterative()
{
int res = GetLen(root);
Console.WriteLine("The Height Of Tree Is: "+res);
}
Iterative version:
private class NodeInfo
{
public NodeInfo(TreeNode node, int len)
{
Node = node;
Len = len;
}
public TreeNode Node {get; private set;}
public int Len {get; private set;}
}
public void HeightIterative()
{
int maxLen = 0;
var queue = new Queue<NodeInfo>();
queue.Enqueue(new NodeInfo(root, 1));
while (queue.Count > 0)
{
var item = queue.Dequeue();
var current = item.Node;
var currentLen = item.Len;
if (current.LeftNode != null)
{
queue.Enqueue(new NodeInfo(current.LeftNode, currentLen + 1));
}
if (current.RightNode != null)
{
queue.Enqueue(new NodeInfo(current.RightNode, currentLen + 1));
}
if (currentLen > maxLen)
{
maxLen = currentLen;
}
}
Console.WriteLine("The Height Of Tree Is: " + maxLen);
}
There is a way that does not require any extra space except the queue for storing the nodes.
Add child nodes of a current element and remember size of the queue.
Let each dequeue call decrement the counter
When counter reaches zero that means we are done with current level.
Repeat and count number of times counter reaches zero - this is the depth/height of the tree
Code goes like this :
public int treeDepth(Node root){
int height = 0;
int counterNodesInLevel = 1;
if(root!=null)
{
Queue<Node> queue=new Queue<Node>()
queue.enqueue(root);
while (!queue.isEmpty()){
Node current = queue.dequeue();
counterNodesInLevel -= 1;
if(current.left!=null){
queue.enqueue(current.left)
}
if(current.right!=null){
queue.enqueue(current.right)
}
if (counterNodesInLevel == 0){
height += 1;
counterNodesInLevel = queue.Size();
}
}
}
return height;
}
Time complexity is O(N), space complexity is O(N)
The problem:
You are finding the depth of the left-most node in the first loop, and the right-most in the second, and never interrogating any node that involves going down to the left AND the right.
A solution:
Have a single loop that drills down the left nodes, but adds each right node that it 'skips' into a queue. When you run out of left nodes, pop-off a node form your queue and continue on until the queue becomes empty. You'll need to store the height of each node you put in the queue with that node.
public int Height()
{
int result = GetMaxHeight(this.Root,0);
return result;
}
private int GetMaxHeight(Node<T> node,int count)
{
int leftMax = 0, rightMax = 0;
if (node.Left != null)
{
leftMax = GetMaxHeight(node.Left, count+1);
}
if (node.Right != null)
{
rightMax = GetMaxHeight(node.Right, count + 1);
}
if(node.Left==null && node.Right == null)
{
return count;
}
return Math.Max(leftMax,rightMax);
}