|
|
So what you want to do, is to find only 1 string once?
Because then you could just stream the file, no buffers needed.
[almost]
To visualize this (in case anyone needs the explanation); you can look at it like a state machine, with a state for every character in the string you are searching for (lets call it X). The state machine will keep reading 1 character at a time until it exits. It starts in state 0, and will change to state 1 if it reads a character that matches X[0]. State n will transition to state n+1 if it reads X[n] or to state 0 if it reads anything else. The last state will return the position in the file if it reads X[last]. Every state will return "not found" if it runs out of characters to read.
[/but not quite]
Solution: use the Knuth-Morris-Pratt algorithm, at worst it has to evaluate the same character multiple times, but it never needs to go back (only forward, but skipping characters in a stream is trivial)
Essentially it's doing the same as what I described, but it jumps back to the right state instead of always 0.
That way you only need a constant amount of memory plus the string X.modified on Sunday, March 7, 2010 9:38 AM
|
|
|
|
|
It is a great idea. How come I've never thought it. Thanks.
|
|
|
|
|
You're welcome
|
|
|
|
|
You do know it gets a little bit more complex when the characters in the search string aren't all different, as in: find "anas" in "a long text containing ananas and other stuff"; returning to state 0 isn't always right.
|
|
|
|
|
Ok fine, spoil the fun
So maybe it isn't 0 but more like X.LastIndexOf(char that was read) (or 0 if it wasn't found) - or if it isn't that I might actually have to think and it's the weekend so no thanks
(exercise for the reader?)
My brain got unlazy for a second and remembered the solution - see the edit..modified on Saturday, March 6, 2010 9:56 PM
|
|
|
|
|
Yes, but I think that is not a problem for me. I am looking for a string in the file, no matter where it is.
I think code can express everything, in a better way. Here is my code:
private long DigBinary(string file, string strToDig)
{
FileStream fs = null;
char[] chAim = strToDig.ToCharArray();
char chTemp = '0';
long latestHitBeginningLocation = 0;
int locationInArray = 0;
try { fs = new FileStream(file, FileMode.Open, FileAccess.Read); }
catch { throw new Exception("An error occured while creating the stream."); }
try
{
while (locationInArray < chAim.Length)
{
chTemp = (char)fs.ReadByte();
if( chTemp != chAim[locationInArray] )
locationInArray = 0;
if (chTemp == chAim[locationInArray])
{
if (locationInArray == 0)
latestHitBeginningLocation = fs.Position - 1;
if (locationInArray == chAim.Length)
break;
locationInArray++;
}
else
{
locationInArray = 0;
latestHitBeginningLocation = 0;
}
}
}
catch { throw new Exception("An error occured while reading the file."); }
finally { if (fs != null) { fs.Close(); fs.Dispose(); } }
return latestHitBeginningLocation;
}
And yes, I know that my try-catch is useless.
|
|
|
|
|
that is a horrible piece of "code".
|
|
|
|
|
I am open to suggestions.
|
|
|
|
|
Here are some:
- unspecified catch = deadly sin
- store actual exception as inner exception in functional exception
- user-generated exceptions should inherit from ApplicationException
- two try blocks where one would suffice
- redundant chTemp initialization
- should use using statement
- char[] chAim = strToDig.ToCharArray(); is redundant; use strToDig[index]
And the algorithm is wrong, as I reported earlier.
|
|
|
|
|
Thanks for the advices. I will change the code accordingly.
This algorithm covers my needs. It works, it is fast and it doesn't consume much RAM.
|
|
|
|
|
Similar to StarBP:
use 2 rolling buffers which are the size of the search terms.
initialize by loading data into buffer 1
repeat the following steps:
clear buffer 2
dump buffer 1 into buffer 2
load fresh data into buffer 1
combine the buffers
search the combination
If the buffers are the correct size your search terms will always be in one combination.
The overhead is that you will be searching each buffer twice though.
hope it helps
Shane
|
|
|
|
|
Dear coders.
If you would not mind taking a look at this page...
http://www.licenturion.com/xp/fully-licensed-wpa.txt
If you see that the installation id is a string of digits, very long... e.g
234344-345656-898909-878766-567676-555655-454334-565556-77 etc
When the check digits are removed, it ends up as a 42 digit number, and this is represented as a byte array encoding of this, 17 bytes long.
How do i get the above long string of digits into its 17 byte representation?
I do not simply want a byte array the same lenght of the string (i.e. 41 digits) I need an actual byte array of 17 digits that represent the numer.
Basacaly, i need to be able to generate the byte array of the string above and vice versa (it may be a base-10 representation.
If no one can help, how can i do the following?
Have a byte array like
BYTE[] = {0x44, 0x34, 0x22, 0x47, 0x49, 0x78, 0x54, 0xf3, 0x2a, 0x44, 0x44, 0x28, 0x44, 0x83,
0x33, 0x22, 0x44}
17 bytes, to represent an encoding of a long number of forty something digits in a string of:
034333-495655-345444-090986-091232 etc....
Basacily as in the text above.
Thank you
Steve
|
|
|
|
|
There may be something in the GMP Bignum Library that can help you. Try searching the Internet for GMP C# bindings.
|
|
|
|
|
Thank you i will try that,
However, there was a simple block of code i found but i cannot find it.
Is there some code that will convert/encode a byte array as a BASE-10 encoding, and one to decode.
I can find many that will encode my byte array to represent base 24, base 32 or HEX but not a string of digits (base 10)
Thank you
Steve
|
|
|
|
|
If I wanted to do this I probably would download the source code mentioned in the document, open up main.c, read it, find that the DecodeInstID function implements the algorithm, and then translate that into C#. Is this what you did, but then forgot?
Alan.
|
|
|
|
|
Yes but it has been so long i have forgot my c and i tried that but cant figure it out.
Steve
|
|
|
|
|
Hello. I have searched for a way to P/Invoke the Graphics.FillPolygon(Brush, Point[]) method. I saw that it is much faster to do so (likely because it bypasses error checking that is unneeded in a well-made program). However, I have not found any examples of how to do so (even .NET Reflector is of no help, only referring me to a P/Invoke that uses a private native field). Please help me translate this code into a P/Invoke. The FillPolygon method is the most important by far, as it is called 10 times more often in the real code as the Clear method is. This Render method takes up an average of 75% of the time in the code, as profiled by NProf (a specially modified version that samples 5x as often as usual was used).
public static void Render(Color color, SolidBrush brush, Point[] points, Graphics graphics)
{
graphics.Clear(color);
graphics.FillPolygon(brush, points);
}
|
|
|
|
|
This is the MSDN page[^] for the Polygon function in gdi32. You need to set the brush and fill mode first and it will draw it filled for you.
[Added]This page[^] gives you the gdi+ function signatures[/Added]
|
|
|
|
|
Thanks, but how do I apply this using C# code? Oh, and what you showed me is normal GDI. System.Graphics uses GDI+. Is this any problem? (I have heard normal GDI is faster, though; is this true?). Here is a slightly modified version of the context within which the code is used:
if (!isPerformanceTest)
{
Renderer.Render(newDrawing , g));
}
bitmapData = bitmap.LockBits(
new Rectangle(0, 0, (int)(Tools.MaxWidth / reduction), (int)(Tools.MaxHeight / reduction)),
ImageLockMode.ReadOnly,
PixelFormat.Format32bppArgb);
I would like some code if at all possible.
|
|
|
|
|
I'd have to work at and test a C# PInvoke method. I have edited the original post with a link to the MSDN GDI+ page[^] with the GdipFillPolygon function signature (gdipluss.dll).
|
|
|
|
|
Here is the complete source code of the program. It may only be used under the provisions of the GPL. This is not Roger Alsing's original work; it has been very highly optimized. Further optimization of other sections is almost useless without optimization of the renderer. I tried Direct3D, which was very good, but it had WAY too many bugs to even attempt to continue on. The Render method is in the Renderer.cs file and is called by FitnessCalculator.cs, which is in turn called by MainForm.cs. The DnaPolygon.cs and DnaDrawing.cs files are used extensively.
Download Source Code
The two lines of the Render method that I mentioned in the original post together take more than 70% of the CPU time of the program.
|
|
|
|
|
Hi,
I am trying to create a web software that will get a URL where is has a long list of links (each link lead to a pge where i want to check a certain filed and get its data), and from that moment on will run alone, using the 'back' option to get back to the previous page where it has the list, then entering the next link and so on.
How can I do that? I know I can cntrol IE but I am not sure if it will be enough...
Thanks for any help ninjas
|
|
|
|
|
You don't need a browser for that, it is much easier using just (Http)WebRequest and (Http)WebResponse, then somewhat parse the HTML page you get.
BTW: Make sure to keep a list of URLs already visited, to prevent running in circles.
|
|
|
|
|
Hi Luc thank you very much for your help!
Will i be able to navigate from that page? As if clicked the 'back' button?
and thanks for the tip with list it will definitely help me saving some time
|
|
|
|
|