why doesn't it terminate? - algorithm

var m_root : Node = root
private def insert(key: Int, value: Int): Node = {
if(m_root == null) {
m_root = Node(key, value, null, null)
}
var t : Node = m_root
var flag : Int = 1
while (t != null && flag == 1) {
if(key == t.key) {
t
}
else if(key < t.key) {
if(t.left == null) {
t.left = Node(key, value, null, null)
flag = 0
} else {
t = t.left
}
} else {
if(t.right == null) {
t.right = Node(key, value, null, null)
flag = 0
} else {
t = t.right
}
}
}
t
}
I wrote iterative version insert a node to binary search tree. I want to terminate when node is created, but it doesn't stop, because I think I didn't assign terminating condition. How to I edit my code to terminate when a node inserted in?

I'm not sure exactly what behaviour you want, but the cause is quite clear.
Your loop is a while condition, which will loop until t is null. So while t is non-null the loop will continue.
You only ever assign t to non-null values - in fact you're specifically checking for the null case and stopping it happening by creating a new node.
So either you need to reconsider your loop condition, or ensure t does in fact become null in some cases, depending on what your actual algorithm requirements are.
And since you're returning t at the bottom, I suggest the while condition is wrong; the only possible way this could terminate is if t is null at this point, so it would be pointless to return this anyway.

The first clause of your "if" statement in the loop
if(key == t.key) {
t
}
... does nothing if the comparison is true. It doesn't terminate the loop. The statement t is not synonymous with return t here. You can set flag = 0 at that point to terminate the loop.

Related

Deleting duplicate nodes from a sorted linked list

I'm trying to delete duplicate nodes from a sorted linked list. The code I used is -
Node* RemoveDuplicates(Node *head)
{
struct Node *ptr = head;
int var = ptr->data;
while(ptr != NULL)
{
var = ptr->data;
if(var == ptr->next->data)
{
ptr->next = ptr->next->next;
else
ptr = ptr->next;
}
return head;
}
Forget the free(ptr) statement, other than that I guess everything is fine but the above code is not working.
Is there any problem in the logic as I saw a similar code online but with one additional pointer?
Thanks in advance.
if(var == ptr->next->data)
should be
if (ptr->next != NULL && var == ptr->next->data)
No guarantees in your code that the next pointer is not null,

Null Reference Exception despite checking for Null

I'm reading from an XML file with C# that has a dynamically generated number of nodes named Col1, Col2, etc. When I attempt to run a while loop on these nodes and check for null I still get a NullReferenceException. Can anyone suggest on how to handle this to avoid the exception?
int col = 1;
string colCount = col.ToString();
colCount = "Col" + colCount;
while (nodes[0][colCount].InnerText != null)
{
timeToFillValues.Add(double.Parse(nodes[0][colCount].InnerText));
col++;
colCount = "Col" + col.ToString();
}
Since you mentioned in comments the error happens when checking condition, there are only few cases where you should be getting an error:
if(nodes == null)
{
// was nodes not populated? Then populate it
}
if(nodes[0][colCount] == null)
{
// does element actually exist or is it null?
}
Check for these conditions before calling the while loop and you should find out wha tis causing the issue.

How to terminate a while loop when an Xpath query returns a null reference html agility pack

I'm trying to loop through every row of a variable length table on the a webpage (http://www.oddschecker.com/golf/the-masters/winner) and extract some data
The problem is I can't seem to catch the null reference and terminate the loop without it throwing an exception!
int i = 1;
bool test = string.IsNullOrEmpty(doc.DocumentNode.SelectNodes(String.Format("//*[#id='t1']/tr[{0}]/td[3]/a[2]", i))[0].InnerText);
while (test != true)
{
string name = doc.DocumentNode.SelectNodes(String.Format("//*[#id='t1']/tr[{0}]/td[3]/a[2]", i))[0].InnerText;
//extract data
i++;
}
try-catch statements don't catch it either:
bool test = false;
try
{
string golfersName = doc.DocumentNode.SelectNodes(String.Format("//*[#id='t1']/tr[{0}]/td[3]/a[2]", i))[0].InnerText;
}
catch
{
test = true;
}
while (test != true)
{
...
The code logic is a bit off. With the original code, if test evaluated true the loop will never terminates. It seems that you want to do checking in every loop iteration instead of only once at the beginning.
Anyway, there is a better way around. You can select all relevant nodes without specifying each <tr> indices, and use foreach to loop through the node set :
var nodes = doc.DocumentNode.SelectNodes("//*[#id='t1']/tr/td[3]/a[2]");
foreach(HtmlNode node in nodes)
{
string name = node.InnerText;
//extract data
}
or using for loop instead of foreach, if index of each node is necessary for the "extract data" process :
for(i=1; i<=nodes.Count; i++)
{
//array index starts from 0, unlike XPath element index
string name = nodes[i-1].InnerText;
//extract data
}
Side note : To query single element you can use SelectSingleNode("...") instead of SelectNodes("...")[0]. Both methods return null if no nodes match XPath criteria, so you can do checking against the original value returned instead of against InnerText property to avoid exception :
var node = doc.DocumentNode.SelectSingleNode("...");
if(node != null)
{
//do something
}

removing nesting of if statements

I have a piece of code, which I am not sure how to refactor.. It is not very readable and I would like to make it readable. Here is a the problem
There are two columns in database which can be either NULL, 0 or have a value each. On the web page there is a checkbox - enable and text box - value for each of those two columns.
x = checkbox1
z = textbox1
y = checkbox2
w = textbox2
The logic is if both the checkboxes are not selected, then both the values should be 0. If either one is selected and other is not, then others value should be NULL. and for the one that is selected, if the textbox is empty its value should be NULL else should be the value in the textbox
if{x}
{
if(z)
{
a = NULL;
}
else
{
a = z;
}
if(y)
{
if(w)
{
b=w;
}
else
{
b = NULL;
}
}
else
{
b = null
}
}
else
{
if(y)
{
a = NULL;
if(w)
{
b=w;
}
else
{
b = NULL;
}
}
else
{
a = 0;
b = 0;
}
}
Trust me this is a valid scenario. Let me know if this makes sense or I should give more information
Using some logical ands and nots, we get something more readable.
We can save a little by defaulting to NULL (thus not needing to set the other to NULL). We can also save by putting the code for checking if a textbox is set or using null into a little function.
In pseudo code:
a = NULL
b = NULL
if (not checkbox1) and (not checkbox2):
a = 0
b = 0
if (checkbox1):
a = valueornull(textbox1)
if (checkbox2):
b = valueornull(textbox2)
function valueornull(textbox):
if textbox value:
return value
else:
return null
I think it would help to use more descriptive names that the single letters here, but assuming this is C code, it looks a lot neater with inline if statements:
if(x)
{
a = z ? NULL : z;
b = (y && w) ? w : NULL;
}
else
{
a = y ? NULL : 0;
b = (y && w) ? w : 0;
}

text box percentage validation in javascript

How can we do validation for percentage numbers in textbox .
I need to validate these type of data
Ex: 12-3, 33.44a, 44. , a3.56, 123
thanks in advance
sri
''''Add textbox'''''
<asp:TextBox ID="PERCENTAGE" runat="server"
onkeypress="return ispercentage(this, event, true, false);"
MaxLength="18" size="17"></asp:TextBox>
'''''Copy below function as it is and paste in tag..'''''''
<script type="text/javascript">
function ispercentage(obj, e, allowDecimal, allowNegative)
{
var key;
var isCtrl = false;
var keychar;
var reg;
if (window.event)
{
key = e.keyCode;
isCtrl = window.event.ctrlKey
}
else if (e.which)
{
key = e.which;
isCtrl = e.ctrlKey;
}
if (isNaN(key)) return true;
keychar = String.fromCharCode(key);
// check for backspace or delete, or if Ctrl was pressed
if (key == 8 || isCtrl)
{
return true;
}
ctemp = obj.value;
var index = ctemp.indexOf(".");
var length = ctemp.length;
ctemp = ctemp.substring(index, length);
if (index < 0 && length > 1 && keychar != '.' && keychar != '0')
{
obj.focus();
return false;
}
if (ctemp.length > 2)
{
obj.focus();
return false;
}
if (keychar == '0' && length >= 2 && keychar != '.' && ctemp != '10') {
obj.focus();
return false;
}
reg = /\d/;
var isFirstN = allowNegative ? keychar == '-' && obj.value.indexOf('-') == -1 : false;
var isFirstD = allowDecimal ? keychar == '.' && obj.value.indexOf('.') == -1 : false;
return isFirstN || isFirstD || reg.test(keychar);
}
</script>
You can further optimize this expression. Currently its working for all given patterns.
^\d*[aA]?[\-.]?\d*[aA]?[\-.]?\d*$
If you're talking about checking that a given text is a valid percentage, you can do one of a few things.
validate it with a regex like ^[0-9]+\.?[0-9]*$ then just convert that to a floating point value and check it's between 0 and 100 (that particular regex requires a zero before the decimal for values less than one but you can adapt it to handle otherwise).
convert it to a float using a method that raises an exception on invalid data (rather than just stopping at the first bad character.
use a convoluted regex which checks for valid entries without having to convert to a float.
just run through the text character by character counting numerics (a), decimal points (b) and non-numerics (c). Provided a is at least one, b is at most one, and c is zero, then convert to a float.
I have no idea whether your environment support any of those options since you haven't actually specified what it is :-)
However, my preference is to go for option 1, 2, 4 and 3 (in that order) since I'm not a big fan of convoluted regexes. I tend to think that they do more harm than good when thet become to complex to understand in less than three seconds.
Finally i tried a simple validation and works good :-(
function validate(){
var str = document.getElementById('percentage').value;
if(isNaN(str))
{
//alert("value out of range or too much decimal");
}
else if(str > 100)
{
//alert("value exceeded");
}
else if(str < 0){
//alert("value not valid");
}
}

Resources