Determinig all leafs nodes in a tree - recursion

Can you guys help me with this method?
I had it with a return before but it didnt work either
private String leafNodes(TreeNode root, String leafs){
if (root.isLeaf()) {
leafs += Integer.toString(root.getData());
}
else {
if(root.getLeft() != null) {
leafs += leafNodes(root.getLeft(), leafs);
}
if (root.getRight() != null) {
leafs += leafNodes(root.getRight(), leafs);
}
return leafs;
}
return leafs;
}

The problem is that you pass leafs to the children and then add the result to the current string so the same leaf can appear several times in the returned string. You can fix it this way:
private String leafNodes(TreeNode root){
String leaves = "";
if (root.isLeaf()) {
leaves = Integer.toString(root.getData());
}
else {
if(root.getLeft() != null) {
leaves += leafNodes(root.getLeft());
}
if (root.getRight() != null) {
leaves += leafNodes(root.getRight());
}
}
return leaves;
}

Related

DevExpress GridControl Does not Update properly even I set up the NotifyPropertyChanged event correctly

I met a very strange Problem.
The basic idea is that I have a class to save data received from a trading api about forex price. Each property has been set with NotifyPropertyChanged method like below.
class RealTimeBar
{
public event PropertyChangedEventHandler PropertyChanged;
private const double EPSILON = 0.0000001;
private int _id;
private string _symbol;
private int _time;
private float _open;
private float _high;
private float _low;
private float _close;
int _volume;
public RealTimeBar(int id, string symbol)
{
_id = id;
_symbol = symbol;
}
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public int Id
{
get
{
return _id;
}
set
{
_id = value;
}
}
public string Symbol
{
get
{
return _symbol;
}
set
{
if (value != _symbol)
{
_symbol = value;
NotifyPropertyChanged("Symbol");
}
}
}
public int Time
{
get
{
return _time;
}
set
{
if (value != _time)
{
_time = value;
NotifyPropertyChanged("Time");
}
}
}
public float Open
{
get
{
return _open;
}
set
{
if (value != _open)
{
_open = value;
NotifyPropertyChanged("Open");
}
}
}
public float High
{
get
{
return _high;
}
set
{
if (value != _high)
{
_high = value;
NotifyPropertyChanged("High");
}
}
}
public float Low
{
get
{
return _low;
}
set
{
if (value != _low)
{
_low = value;
NotifyPropertyChanged("Low");
}
}
}
public float Close
{
get
{
return _close;
}
set
{
if (value != _close)
{
_close = value;
NotifyPropertyChanged("Close");
}
}
}
public int Volume
{
get
{
return _volume;
}
set
{
if (value != _volume)
{
_volume = value;
NotifyPropertyChanged("Volume");
}
}
}
}
It is quote a long class but with simple structure as you can see. Now I connected to api which fire event to me and I handle it by set the value from api to the class i defined.
BindingList<RealTimeBar> _realTimeBarList = new BindingList<RealTimeBar>();
public Hashtable _iForexHashtable = new Hashtable();
private void _UpdateForexQuote(int tickerId, int time, double open, double high, double low, double close, int volume,
double wap, int count)
{
///MessageBox.Show(tickerId.ToString());
((RealTimeBar)_iForexHashtable[tickerId]).Open = (float)open;
((RealTimeBar)_iForexHashtable[tickerId]).High = (float)high;
((RealTimeBar)_iForexHashtable[tickerId]).Low = (float)low;
((RealTimeBar)_iForexHashtable[tickerId]).Close = (float)close;
((RealTimeBar)_iForexHashtable[tickerId]).Volume = volume;
}
After some setting up, the method _UpdateForexQuote would distribute the coming info into properties of RealTimeBar class. Everything is fine.
When I start the program, it does not update. I thought that there is no data coming in. But when I randomly click somewhere in the A1cell of gridcontrol, then click another B1cell, the previous A1cell would update. Then if i click C1cell, then the B1cell would update. If you do not click one cell , it would never update. I show you the picture:
As you can see, that after clicking first three lines, the first three lines showed delayed data and since I never touch the fourth line, it shows zero. And the condition is that I just clicked the fifth line Low cell, that is why the Low does not update but other cells updated. It is very strange. I use same code before under devexpress 11 with vs 2010. But now with devexpress 12 with vs 2012, I met this problem which never occurred before.
UPDATE:
Below is the method I use to 1. define bindinglist and a hashtable, 2. put objects into the hashtable first and add the object from hashtable to bindinglist 3. bind the bindinglist to gridcontrol.
private void earningButtonItem_ItemClick(object sender, ItemClickEventArgs e)
{
_iTimer.AutoReset = false;
_iTimer.Enabled = false;
switchStockPool = "Earning Stock";
disconnectButtonItem.PerformClick();
connectButtonItem.PerformClick();
_iheitanshaoEarningDBConnect = new DBConnect("heitanshaoearning");
List<string>[] tempList;
int tempHash;
tempList = _iheitanshaoEarningDBConnect.SelectSymbolHighLow();
_quoteEarningOnGridList.Clear();
///tempList[0].Count
for (int i = 0; i < tempList[0].Count; i++)
{
tempHash = Convert.ToInt32(tempList[0][i].ToString().GetHashCode());
_iStockEarningHistHashtable[tempHash] = new QuoteOnGridHist(tempList[0][i], (float)Convert.ToSingle(tempList[1][i]), (float)Convert.ToSingle(tempList[2][i]), (float)Convert.ToSingle(tempList[3][i]));
_iStockEarningHashtable[tempHash] = new QuoteOnGrid(tempList[0][i], 0, 0);
_quoteEarningOnGridList.Add((QuoteOnGrid)_iStockEarningHashtable[tempHash]);
reqMktDataExStock(tempHash, tempList[0][i].ToString());
}
List<string>[] tempVolumeList;
tempVolumeList = _iheitanshaoEarningDBConnect.SelectAverageVolume();
for (int i = 0; i < tempList[0].Count; i++)
{
tempHash = Convert.ToInt32(tempVolumeList[0][i].ToString().GetHashCode());
((QuoteOnGrid)_iStockEarningHashtable[tempHash]).Average_Volume = ((float)Convert.ToSingle(tempVolumeList[1][i])) / volumeDenominator;
}
gridControl.DataSource = _quoteEarningOnGridList;
}
/////////////////////
Now when the price update event comes, the method below will update the object properties in hashtable. Since I defined Notifypropertychanged in object, it should update the object in bingdinglist and gridcontrol.
private void _UpdateStockMarketQuote(int tikcerId, int field, double price, int canAutoExecute)
{
////MessageBox.Show(tikcerId.ToString() + field.ToString() + price.ToString());
if (switchStockPool == "Selected Stock")
{
if (field == 4)
{
((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_High = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).High) / ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close;
((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_Low = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Low) / ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close;
((QuoteOnGrid)_iStockHashtable[tikcerId]).Last_Price = (float)price;
}
//else if (field == 1)
//{
// ((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_High = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).High) / ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close;
// ((QuoteOnGrid)_iStockHashtable[tikcerId]).Gap_From_Low = ((float)price - ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Low) / ((QuoteOnGridHist)_iStockHistHashtable[tikcerId]).Close;
//}
}
else if (switchStockPool == "Earning Stock")
{
if (field == 4)
{
((QuoteOnGrid)_iStockEarningHashtable[tikcerId]).Gap_From_High = ((float)price - ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).High) / ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).Close;
((QuoteOnGrid)_iStockEarningHashtable[tikcerId]).Gap_From_Low = ((float)price - ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).Low) / ((QuoteOnGridHist)_iStockEarningHistHashtable[tikcerId]).Close;
((QuoteOnGrid)_iStockEarningHashtable[tikcerId]).Last_Price = (float)price;
}
//else if (field == 1)
//{
// ((quoteongrid)_istockearninghashtable[tikcerid]).gap_from_high = ((float)price - ((quoteongridhist)_istockearninghisthashtable[tikcerid]).high) / ((quoteongridhist)_istockearninghisthashtable[tikcerid]).close;
// ((quoteongrid)_istockearninghashtable[tikcerid]).gap_from_low = ((float)price - ((quoteongridhist)_istockearninghisthashtable[tikcerid]).low) / ((quoteongridhist)_istockearninghisthashtable[tikcerid]).close;
//}
}
}
Not only you need to have PropertyChanged event in a class, you need to implement INotifyPropertyChanged. That's how the grid knows a class can inform of changes.

What is the contents of the Request[] collection

When I access the Request object as a collection, where does it get it's data from?
For example I know
Request["someKey"]
will return the value of either
Request.QueryString["someKey"]
or
Request.Form["someKey"]
depending on which is set.
Are any other collections searched (cookies, session)?
What happens is the key value pair exists in several of the collections?
I took a look in MSDN, but couldn't find much info.
http://msdn.microsoft.com/en-us/library/system.web.httpcontext.request
Thanks for the help!
If you decompile this assembly and take a look at the source, it will look in QueryString, then Form, then Cookies, then ServerVariables, before finally returning null if none of them contain the item.
public string this[string key]
{
get
{
string item = this.QueryString[key];
if (item == null)
{
item = this.Form[key];
if (item == null)
{
HttpCookie httpCookie = this.Cookies[key];
if (httpCookie == null)
{
item = this.ServerVariables[key];
if (item == null)
{
return null;
}
else
{
return item;
}
}
else
{
return httpCookie.Value;
}
}
else
{
return item;
}
}
else
{
return item;
}
}
}

regular expression asp.net

I trying to improve a textbox that filters a gridview, by implementing an enhanced textbox that can identify AND, OR, NOT operators by searching for this keywords in the string the user inputs in the textbox.
I am trying to do a regular expression to group the results but I'm not very good at this and I am failing to get what I want.
An example of what I want is as follows:
string = "build1 and build2 and build3 or build4 or not build5 and not build6"
results in a split mode:
build1 and
build2 and
build3 or
build4 or not
build5 and not
build6
This is because then I will take the first for example and replace with
SomeTable.Name_Of_Build = 'build1' AND
SomeTable.Name_Of_Build = 'build2' AND .... so on
This works for me
\w+(\sand\snot|\sor\snot|\sand|\sor|$)
I might recommend that instead of using a regular expression to group the results you do something like this. I think it would be more robust than trying to guess at the right regex.
string filter = "build1 and buil2 and build3 or build4 or not build5"
list<string> filterTokens = filter.Split(new char[] {' '})
string gridViewFilter = "";
bool notEqual = false;
foreach(string token in filterTokens)
{
if(token == "and")
{
gridViewFilter += "and"
}
else if(token == "or")
{
gridViewFilter += "or"
}
else if(token == "not")
{
notEqual = true;
}
else if(notEqual)
{
gridViewFilter += "SomeTable.Name_Of_Build <> '" + token + "'";
notEqual = false;
}
else
{
gridViewFilter += "SomeTable.Name_Of_Build <> '" + token + "'";
}
}
Also, if you really want to implement a robust and full featured sort you need to look into using Reverse Polish Notation (RPN). It would allow you to handle parentheses and order of operations. An RPN implementation would look something like this.
private bool CheckForFilterMatch(string filter, List<string> values, bool exactMatch)
{
for (int i = 0; i < values.Count; i++)
{
values[i] = values[i].ToLower();
}
if (filter.Trim() == "")
{
return true;
}
List<string> rpn = GetPostFixNotation(filter);
Stack<bool> output = new Stack<bool>();
foreach (string token in rpn)
{
if (IsValue(token))
{
bool isMatch;
if (exactMatch)
{
isMatch = values.Contains(token.ToLower());
}
else
{
isMatch = false;
foreach (string value in values)
{
isMatch = (value.IndexOf(token.ToLower()) != -1);
if (isMatch) break;
}
}
output.Push(isMatch);
}
else if (IsOperator(token))
{
bool operand1 = output.Pop();
bool operand2 = output.Pop();
if (token == "&")
{
output.Push(operand1 && operand2);
}
if (token == "|")
{
output.Push(operand1 || operand2);
}
}
}
return output.Pop();
}
public List<string> GetPostFixNotation(string filter)
{
if (filter == "")
{
return new List<string>();
}
List<string> postFixNotation = new List<string>();
Queue<string> output = new Queue<string>();
Stack<string> operators = new Stack<string>();
List<string> parsedFilter = ParseFilterTokens(filter);
foreach (string token in parsedFilter)
{
if (IsValue(token))
{
output.Enqueue(token);
}
else if (IsOperatorNoParenth(token))
{
while (operators.Count > 0 && IsOperatorNoParenth(operators.Peek()))
{
if ((operators.Count > 0 && (Precedence(token) <= Precedence(operators.Peek()))))
{
string operatorToReturn = operators.Pop();
output.Enqueue(operatorToReturn);
}
else break;
}
operators.Push(token);
}
else if (token == "(")
{
operators.Push(token);
}
else if (token == ")")
{
while (operators.Count > 0 && operators.Peek() != "(")
{
output.Enqueue(operators.Pop());
}
operators.Pop();
}
}
while (operators.Count > 0)
{
output.Enqueue(operators.Pop());
}
while (output.Count > 0)
{
postFixNotation.Add(output.Dequeue());
}
return postFixNotation;
}
Try this regex out:
(build[^b]+)

How can I get the value of a parameter passed to a method in a custom rule in FxCop?

Due to certain reasons, in our ASP.NET web application, it is not recommended to use Response.Redirect("something", True). It should be used with False for the endResponse parameter. We want to enforce this with a custom FxCop rule.
I've managed to find the usages of Response.Redirect, but now I want to find the value of the endResponse argument. How can I do this?
We're using the following code:
public override ProblemCollection Check(Member member)
{
var method = member as Method;
if (method != null)
{
foreach (var instruction in method.Instructions)
{
switch (instruction.OpCode)
{
case OpCode.Call:
case OpCode.Callvirt:
case OpCode.Newobj:
var call = (Method) instruction.Value;
if (call == null)
{
break;
}
if (call.Name.Name != "Redirect")
{
break;
}
if (call.Parameters.Count == 1)
{
//Redirect(url)
var resolution = GetResolution();
var problem = new Problem(resolution);
Problems.Add(problem);
}
if (call.Parameters.Count == 2)
{
VisitStatements(call.Body.Statements);
}
break;
default:
break;
}
}
}
return Problems;
}
public override void VisitExpression(Expression expression)
{
var methodCall = expression as MethodCall;
if (methodCall == null)
{
return;
}
foreach (var operand in methodCall.Operands)
{
if (operand.Type.Name.Name == "Int16" || operand.Type.Name.Name == "Int32" || operand.Type.Name.Name == "Int64")
{
var literal = operand as Literal;
if (literal != null && literal.Value is int)
{
var literalValue = (int)literal.Value;
if (literalValue == 1)
{
var resolution = GetResolution();
var problem = new Problem(resolution);
Problems.Add(problem);
}
}
}
}
}
I've used Introspector and thought the endResponse parameter was an integer behind the scenes, but I'm not so sure anymore. Anyway, there don't seem to be any booleans in the methodCall.Operands.
Has anyone ever had a similar situation, where you need to check the actual value of a parameter that's passed to a method?
While the parameter type is actually a System.Boolean, the FxCop IL parser is treating it as an integer. Here's a simplified version of the rule that should work (assuming you want non-literal endResponse values to trigger a rule violation):
public override ProblemCollection Check(Member member)
{
Method method = member as Method;
if (method != null)
{
this.Visit(method.Body);
}
return this.Problems;
}
public override void VisitMethodCall(MethodCall call)
{
base.VisitMethodCall(call);
Method targetMethod = (Method)((MemberBinding)call.Callee).BoundMember;
if (targetMethod.DeclaringType.FullName.Equals("System.Web.HttpResponse", StringComparison.Ordinal) &&
targetMethod.Name.Name.Equals("Redirect", StringComparison.Ordinal))
{
bool callIsAcceptable = false;
if (targetMethod.Parameters.Count == 2)
{
Expression endResponseOperand = call.Operands[1];
if (endResponseOperand.NodeType == NodeType.Literal)
{
if ((int)((Literal)endResponseOperand).Value == 1)
{
callIsAcceptable = true;
}
}
}
if (!callIsAcceptable)
{
this.Problems.Add(new Problem(this.GetResolution(), call));
}
}
}

It throws an stackoverflow exception when I user PropertyInfo.SetValue()

When I use PropertyInfo.SetValue in asp.net , it throws a stackoverflow exception.
That I write this code:
for (int i = 0; i < rivalSeriesIDList.Count; i++)
{
cardb_series rivalSeries = seriesBll.GetSeriesInfoByID(rivalSeriesIDList[i].ToString());
this.GetType().GetProperty("brandid" + (i + 1)).SetValue(this, rivalSeries.brand_id, null);
this.GetType().GetProperty("seriesid" + (i + 1)).SetValue(this, rivalSeries.series_id, null);
}
And brandid+number and seriesid+number is a property of aspx_page. like this:
public int brandid1
{
get
{
if (Request.Form["brandid1"] != null)
return int.Parse(Request.Form["brandid1"]);
if (Request["brandid1"] != null)
return int.Parse(Request["brandid1"]);
return 0;
}
set
{
brandid1 = value;
}
}
when I test the code in a Console Application ,It is all right . But when I test it in a Web Application ,it will cause a stack overflow exception .
I don't know why. Because of web is no-state?
Thanks.
cause you call your property recursively, and will get the same exception even if you will call the property directly
public int brandid1 <- this one
{
get
{
if (Request.Form["brandid1"] != null)
return int.Parse(Request.Form["brandid1"]);
if (Request["brandid1"] != null)
return int.Parse(Request["brandid1"]);
return 0;
}
set
{
and this one -> brandid1 = value;
}
}
I don't know what do you want to do, but try this
private int _brandid1;
public int brandid1 <- this one
{
get
{
if (Request.Form["brandid1"] != null)
return int.Parse(Request.Form["brandid1"]);
if (Request["brandid1"] != null)
return int.Parse(Request["brandid1"]);
return 0;
}
set
{
_brandid1 = value;
}
}

Resources