|
I'm looking for a reversed insertion sort. I would like to, as usual, take a number (the first) in the right part of the array and then, as opposed to the standard, start looking at the last item in the left array and then work my way to the beginning of the left part of the array.
My current solution for this is the below I wonder if someone has a better (cleaner version). I doubt mine is as good as i gets...
(Why? - school assigment...)
/Rgds
public int[] InsertReversed(int[] arr)
{
for (int h = 1; h < arr.Length; h++)
{
int curr = arr[h];
int v = h - 1;
for (; v >= 0; v--)
{
if (curr > arr[v])
break;
}
for (int i = h; i > v+1; i--)
{
arr[i] = arr[i - 1];
}
arr[v+1] = curr;
}
return arr;
}
|
|
|
|
|
Well huh?
You have to write an Insertion Sort that starts searching for the insertion location from the back of the sorted part, and you want to optimize it? (not much to do then, I only see 1 thing right now)
Or do you want to optimize insertion sort? (that would be easier)
|
|
|
|
|
Hi, thanks.
Yes, only looking for optimizing this one for now. We are looking at merge, heap and quick as well. I figured it wasn't much to do about what I've got but if you found one thing it would be greatly appreciated.
Rgds
|
|
|
|
|
The thing I found is ..
edit: wait a minute I'll figure this out..
There is something else though, which is the algorithm. And I don't mean that you should use a different kind of sort, but I mean the "search backwards" part. This backwards searching only helps for certain inputs, as you probably know. Since the first part is sorted, you could do a binary search. It doesn't affect the "big O" of course but for random inputs it would work better on average since less time would be spent searching for the correct place, assuming the array is big enough to hide the Nasty Constant hidden by the big O.
On the other hand, insertion sort would be the wrong choice for random inputs.
It could be worth investigating, though.
edit2: ok back to this "1 thing".
The original "copy loop" is
for (int i = h; i > v + 1; i--)
{
arr[i] = arr[i - 1];
}
The new loop would be:
for (int i = h - 1; i > v; i--)
{
arr[i + 1] = arr[i];
}
And I'll have to conclude that it could be faster, but the CLR is a bit of an idiot, especially in debug mode which is the only think I can quickly test (it does things like storing the result of the loop condition on the stack - presumably for the debugger to know the result of the comparison). In C++ or C this kind of trick would work (if the compiler didn't think of it first) and it might work for C# in release mode.
I'll run some tests.
Edit: yes, it is approximately 4% faster, with array length 1k. 5.5% with array length 10k.
Edit2: this result may be insignificant.
There may also be a way to avoid array-bounds checks (well, 1 per iteration max anyway), I'll look into it.
Edit: no, there isn't.
modified on Thursday, June 3, 2010 8:16 AM
|
|
|
|
|
I also tried unsafe code, it got 13% faster (array size 10k).
The code was:
unsafe
{
fixed (int* ptr = &arr[0])
{
for (int i = h - 1; i > v; i--)
{
ptr[i + 1] = ptr[i];
}
}
}
note: all tests were done without a debugger attached, with a release build, on a 64bit platform.
edit: unsafe code would also help for the other parts of the function, of course.
|
|
|
|
|
|
Hi, I see some server-client applications that connects to each other as long as they are in the same LAN without making specific settings (for example: DeepFreeze program). And some programs requires more specific settings to connect.
So, I want my program to communicate say like deepfreeze, What route should I take for coding?. My program is an internet cafe program and Server will control clients(opening-closing account,sending files, taking screenshot, closing running applications etc.) and clients will be able to: order drinks,send message etc.
Shortly I want the best performance.
Your valuable comments are welcomed, Thanks in advance
|
|
|
|
|
Remoting, WCF, or a TCPIP Listener/client. You could also setup a web service on the server that let the clients submit ordeers, and certain vendor workstations view/process orders.
I think Workflow Foundation would be a decent way to implement this because the vendor workstations would be auto-notified of new orders.
.45 ACP - because shooting twice is just silly ----- "Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "The staggering layers of obscenity in your statement make it a work of art on so many levels." - J. Jystad, 2001
|
|
|
|
|
I've got a user control with 6 or 7 elements that interact with a user; I'd like to notify the host Form whenever any of them change states or values. I've read what I could find at MSDN, along with several of the articles on CP, but I'm still baffled. All I want to do is raise an event to be processed by the host form that passes the name (or .Tag value) of the item that changed. The form can then decide whether to read the new value or not. That seems to me to be something that should be fairly simple, but all I'm finding are articles that are far too complex. So far I've got the following:
public delegate void ValueChangeEvent(string source);
public static event ValueChangeEvent NewValue;
The IDE is sniveling about wanting a body declaration for NewValue, but I have no idea what it wants, nor any clue as to what to do next. Can someone shed some light on this for me?
"A Journey of a Thousand Rest Stops Begins with a Single Movement"
|
|
|
|
|
This may be a sample that could give you a better idea.
What they suggest is that "it is generally recommended that you base your events on the .NET Framework pattern by using EventHandler ".
So, you should probably be doing something like
public event EventHandler ValueChangedEvent;
I hope someone has a better samples on creating your own Events (without using the EventHandler ).
My signature "sucks" today
|
|
|
|
|
Signal an event from a child to a parent
In the child form:
public partial class frmChild : Form
{
public event EventHandler Changed;
protected virtual void OnChanged(EventArgs e)
{
EventHandler eh = Changed;
if (eh != null)
{
eh(this, e);
}
}
private void DoSomethingToChangeData()
{
OnChanged(null);
}
}
----- The asign to eh is in case the handler changes between null check
----- and exec.
----- (unlikely, but possible)
----- The null check is to ensure there is a handler. If not, better to
----- ignore it gracefully, than to rely on the thrown exception
----- (NullReferenceException)
In the Parent form:
public frmParent()
{
frmChild.Change += new frmChange.ChangeHandler(Changed);
}
private void ShowChildForm()
{
frmChild fd = new frmChild();
fd.ShowDialog();
}
private void Changed(object sender, EventArgs e)
{
}
***************************************
You can pass data in this way via the EventArgs parameter:
Child:
public partial class frmOther : Form
{
public frmOther()
{
InitializeComponent();
}
public event EventHandler Changed;
private void butGo_Click(object sender, EventArgs e)
{
EventHandler ch = Changed;
if (ch != null)
{
ch(this, new ChangedArgs(tbData.Text));
}
}
}
public partial class ChangedArgs : EventArgs
{
public string strData;
public ChangedArgs(string str)
{
strData = str;
}
}
Parent:
public partial class frmTextBox : Form
{
frmOther otherForm = new frmOther();
public frmTextBox()
{
InitializeComponent();
}
private void frmTextBox_Load(object sender, EventArgs e)
{
otherForm.Changed += new EventHandler(Changed);
otherForm.Show();
}
private void Changed(object sender, EventArgs e)
{
ChangedArgs ca = e as ChangedArgs;
if (ca != null)
{
tbData.Text = ca.strData;
}
}
}
[edit]Forgot the code block tags. Getting too used to the autopreview in QA I guess...[/edit]
Did you know:
That by counting the rings on a tree trunk, you can tell how many other trees it has slept with.
|
|
|
|
|
Thanks! That's a closer approximation of what I'm doing - I'll study it and try a few things.
"A Journey of a Thousand Rest Stops Begins with a Single Movement"
|
|
|
|
|
>Hi Roger,
I don't know if you came across my article[^] or not - but it works through from the most basic to more complex.
A quick overview...
Events (using the standard .NET model) use a delegate System.EventHandler which has the two familiar parameters object sender, EventArgs e . The sender is the instance that is raising the event, e is where any information is passed (more on this soon).
So, to create an event you need something like:
public event EventHandler MyEvent;
To raise the event from your class instance is a little more complicated.
protected virtual void OnMyEvent(EventArgs e)
{
EventHandler eh = MyEvent;
if(eh != null)
eh(this, e);
} The above method is protected virtual so it only visible within the class or derived classes and can be overriden if required. The e parameter lets the calling code pass the info to the event.
The first line in the message body is there to protect against the possibility that MyEvent may become null between checking for null and raising the event - see next line!
If there are no subscribers, then eh will be null so raising the event would cause an exception so the second line checks for this.
The final line actually raises the event.
That's all there is to it until you need to actually pass some information. EventArgs doesn't have anywhere to put these, so you need to create your own class derived from it e.g.
public class MyEventArgs : EventArgs
{
private int value;
public MyEventArgs(int value)
{
this.value = value;
}
public int Value
{
get { return value; }
}
}
To use these, you can change all the EventHandler references above to EventHandler<MyEventArgs> and EventArgs to MyEventArgs .
Now, all you need to do is call the OnMyEvent method when needed and your event will be raised.
DaveIf this helped, please vote & accept answer!
Binging is like googling, it just feels dirtier. (Pete O'Hanlon)
BTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)
|
|
|
|
|
I don't think I've run across your article yet, Dave. Thanks for the link, and the excellent explanation!
"A Journey of a Thousand Rest Stops Begins with a Single Movement"
|
|
|
|
|
I am using OracleDataReader to read data from our DB (oracle)
The annoying thing is that in a certain column I have a string with a single white-space, however the datareader seems to convert this to a System.DBNull value, which is incorrect.
Does anyone know if there is a setting on the OracleDataReader or perhaps the OracleConnection objects to prevent the conversion from white-space strings to DBNull?
Thanks for any help you can provide,
Davy
|
|
|
|
|
Are you sure that you really have a single whitespace in that column? Try running a select on the table where that column is null. In Oracle, if you insert a trimmed string and the string length is zero, it actually stores it as null.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Ok, this was a really stupid mistake of mine.
Had written a PL/SQL block that replaced for certain rows in particular cases a null value with a singe white space string. BUT here comes the stupidity : forgot to commit...
Was running my .NET app: I got DBNull, was double checking on the session that had run the PL/SQL block which was returning ofcourse the single character string. So committed the changes now and runs like a charm.
|
|
|
|
|
GDavy wrote: forgot to commit...
Been there, seen it, got the T-shirt. Glad you got it sorted.
"WPF has many lovers. It's a veritable porn star!" - Josh Smith As Braveheart once said, "You can take our freedom but you'll never take our Hobnobs!" - Martin Hughes.
My blog | My articles | MoXAML PowerToys | Onyx
|
|
|
|
|
Hi everyone,
I have a project where i need my C# application to communicate with a microcontroller. I have set up a UART communication at 9600 baud, 8 data bits, no parity and 1 stop bit.
i send data using the following function
serialPort1.Write(messageBuf,0,10);
where messageBuf is declared as a byte array containing 10 bytes of data. This works perfect.
My problems is receiving the data form the uC. I use the following code for this:
byte[] messageRead = new byte[8];
serialPort1.Read(messageRead, 0, 8);
where messageRead is declared like this:
byte[] messageRead = new byte[8];
when i check the messageRead buffer i only find data in the first element. I have checked the bus using a logic analyzer and i can clearly see all the 8 bytes being sent out from the uC to the pc but for some reason my program only accepts the first element. I have tried adding delays between the bytes (now i send them immediately after eachother) and increased the serialPort1.ReadTimeout but nothing seems to work. I only recieve one byte.
the first byte arrives at the bus 3ms after request and then the following 7 bytes immediately after.
Any ideas on what im doing wrong?
Thank you!
|
|
|
|
|
OK, let's give you some ideas:
1.
Correctly and reliably receiving serial data is orders of magnitude more difficult, than sending data. Sending is easy, all it takes is a Write() and it will happen eventually. Reading is difficult as you have to read at an appropriate moment, and you may or may not get troubled by data holding messages and messages being chopped to pieces by your reading code.
2.
you did not explain when and where you execute SerialPort.Read(). Is it in a button click handler? a timer tick handler? a DataReceived handler?
3.
When it is a command-response situation, your PC app sends a command to the peripheral; first it takes a few milliseconds for the entire command to leave the PC's serial port; then the peripheral will get those bytes one by one, and probably not do much until the entire command has been received. Then it needs to react to it (interpret command, execute command, maybe wait on the termination of an analog/digital conversion operation, etc), then construct a reply message, then start sending that.
4.
If your PC app sits waiting for the response, it probably wants to react as soon as possible. So having a polling loop or simply use the DataReceived event, will launch the reading code as soon as something got received, however that something will not be the entire reply as it takes about 8 msec for it to travel the serial channel (9600Bd is roughly 1 byte per millisecond). So what to do?
5.
Here are some schemes, none is perfect, you must decide which fits your situation most:
A. not event-driven: wait long enough, then read; as in write,sleep, read.
B. text communication: the serial driver knows about text lines, if you ask for a line of text, you will obtain all characters up to the first end-of-line (You can set the port's NewLine string). This only works for text, and requires your text not to contain an accidental end-of-line in the middle of the data.
C. event-driven: use DataReceived event, and in its handler sleep long enough to cover the time span from first byte to last byte, say 8 milliseconds. Disadvantages: your sleep time will be rounded up to probably 10 to 30 msec (see my timers article), and if your peripheral hesitates in the middle of its transmission, you still won't get it all.
D. use DataReceived event, and don't read until there are enough bytes available; then read. This will fail I guess, as there is no guarantee that each and every incoming byte will cause a DataReceived event.
E. Buffer it yourself: collect incoming data, independent of what you expect; then investigate what you have so far, and when it makes sense, consume it. When it does not, either wait for more, or discard and wait for more.
6.
To complicate matters, communication can go wrong. The other side may suddenly fail; the cable could become disconnected; a byte could get damaged; a parity error could occur; etc. You should code defensively in general, you should do even more so in communication. Therefore (E) above is the best option, not the easiest one.
7.
Conclusion
if you can rely on a unique character to indicate the end of a message (such as a CR or LF in a text string), then that is by far the easiest way to go, as now the driver is in charge of gathering messages. Otherwise, consider your own buffering, read everything, and locate, decode and process packets in your buffer; do not expect messages to always be received correctly without problems (unless you can afford to wait long enough because nothing is urgent and messages are few and far apart).
Luc Pattyn [Forum Guidelines] [Why QA sucks] [My Articles]
I only read formatted code with indentation, so please use PRE tags for code snippets.
I'm not participating in frackin' Q&A, so if you want my opinion, ask away in a real forum (or on my profile page).
|
|
|
|
|
I'm using VS 2008
From a form I pass a class (Facility ) to another class (FCalc ) in the instantiator
Facility is a partial class and has the properties with NotifyPropertyChanged in the setter
The property in question is bound to a textbox text property.
When the Facility value is updated in the FCalc class the textbox is not updated. The NotifyPropertyChanged event is fired but when I get back to the form the values between the Facility object and the textbox are different.
To try and force this through I have used the ReadValue on the DataBinding but this does not help.
txtROE.DataBindings[0].ReadValue();
I have tested the values of the textbox and the object directly after ReadValue() and they are different.
Any suggestions are welcome
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Nothing springs to mind but I found Bind Better with INotifyPropertyChanged[^], don't know if it helps/applies in your situation.
Henry Minute
Do not read medical books! You could die of a misprint. - Mark Twain
Girl: (staring) "Why do you need an icy cucumber?"
“I want to report a fraud. The government is lying to us all.”
Why do programmers often confuse Halloween and Christmas?
Because 31 Oct = 25 Dec.
|
|
|
|
|
Thanks but this looks like a wrapper around INotify to make it apply generically, useful in it's own right by not in this case!
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
I managed to get the desired result by dropping and rebuilding the binding
txtROE.DataBindings.Clear();
Binding oBinding = new Binding("Text", oFSet, "ROE");
oBinding.FormatString = "#,#.00";
oBinding.FormattingEnabled = true;
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Hmm.... Are you certain the Facility object is not re-instantiated somewhere after the binding. That could explain this behaviour.
|
|
|
|
|