Click to See Complete Forum and Search --> : [RESOLVED] [2.0] How to do this..
Fromethius
Feb 22nd, 2007, 05:46 PM
Well.. basically. I am making a program to go:
a
b
c
d
etc..
aa
ab
ac
ad
etc..
ba
bb
bc
bd
etc..
I am using SendKeys to send it to the current screen. What I am wondering though, this being my question, is, how can I override SendKeys to accept a custom amount of parameters? For example:
SendKeys.Send(myArray[x], myArray[y], myArray[z]);
But sometimes it might be 2.. or 7?! Anyways.. I'm just looking for a way to do this... I know I can do it with like.. 4000 if statements but I'd prefer clean code. Yea.. Any ideas = appreciated
jmcilhinney
Feb 22nd, 2007, 07:03 PM
Write a method that takes an array as a parameter, then loops through that array and passes each element to SendKeys.Send.
Fromethius
Feb 22nd, 2007, 08:18 PM
private void Riddler(string[] array)
{
foreach (string s in array)
{
SendKeys.Send("{ENTER}");
SendKeys.Send("-" + s);
SendKeys.Send("{ENTER}");
}
}
Yea that gets me all the way up from 'a' to 'z' but still... afterwards I want it to go:
aa
ab
ac
ad
ae
af
etc...
ba
bb
bc
bd
be
etc..
eventually...
aaa
aab
aac
aad
etc..
aaaa
aaab
aaac
aaad
So yea.. Sorry if I wasn't clear in my original post
jmcilhinney
Feb 22nd, 2007, 08:24 PM
So what are you actually asking for? A way to create all combinations of elements from an array? A way to create all possible combinations of 1 to 4 characters? Something else? If there's a general case then you need to describe the general case because it's the general case you need to design an algorithm for.
Fromethius
Feb 22nd, 2007, 08:42 PM
Yes. All possible combinations. And.. It can go up to like.. 20 letters. I want to be able to stop it midway. Thanks
jmcilhinney
Feb 22nd, 2007, 08:52 PM
How would you do it on paper? Think about the steps you'd use to do it manually and that will give you an algorithm. Once you have an algorithm you can then implement it in code.
Fromethius
Feb 22nd, 2007, 08:56 PM
yea i tried that and it involved a kagillion if statements.. kinda sorta why i came here in the first place. lol
btw john i'm barely 14 so i don't have that advanced math mind yet anyways
jmcilhinney
Feb 22nd, 2007, 09:12 PM
Who let those kids in here. ;) I guess it's that sort of thing that I forget too easily.
This will get you all the combinations:string[] arr1 = { "a", "b", "c", "d" };
string[] arr2 = arr1;
MessageBox.Show(String.Join(",",arr2));
for (int i = 1; i < arr1.Length; i++)
{
string[] arr3 = new string[arr1.Length * arr2.Length];
int arr3Index = 0;
for (int j = 0; j < arr2.Length; j++)
{
for (int k = 0; k < arr1.Length; k++)
{
arr3[arr3Index] = arr2[j] + arr1[k];
arr3Index++;
}
}
arr2 = arr3;
MessageBox.Show(String.Join(",",arr2));
}The MessageBox bits are where you'd use SendKeys if that's what you want to do. If you want to be able to cancel the operation then I'd suggest using a BackgroundWorker and doing the whole thing in the DoWork event handler. You can then cancel the BackgroundWorker from the UI thread and test for a pending cancellation in the worker thread.
Fromethius
Feb 23rd, 2007, 05:09 AM
gracias =)
Fromethius
Feb 23rd, 2007, 02:55 PM
Umm... I think my computer can't handle it? Here is my code. I get a SystemOutOfMemory Exception
public void MyKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F8)
{
string[] arr1 = { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
string[] arr2 = arr1;
for (int x = 0; x < arr2.Length; x++)
{
SendKeys.Send("{ENTER}");
SendKeys.Send(arr2[x]);
SendKeys.Send("{ENTER}");
}
for (int i = 1; i < arr1.Length; i++)
{
string[] arr3 = new string[arr1.Length * arr2.Length];
int arr3Index = 0;
for (int j = 0; j < arr2.Length; j++)
{
for (int k = 0; k < arr1.Length; k++)
{
arr3[arr3Index] = arr2[j] + arr1[k];
arr3Index++;
}
}
arr2 = arr3;
SendKeys.Send("{ENTER}");
SendKeys.Send(arr2[i - 1]);
SendKeys.Send("{ENTER}");
}
}
}
Fromethius
Feb 24th, 2007, 05:54 PM
bump. john, did u find anything on it?
jmcilhinney
Feb 24th, 2007, 06:04 PM
I'll get back to you on this. I've formulated a way to create one string at a time, thus negating the need for large arrays, but I'm not in a position to test it at the moment.
jmcilhinney
Feb 24th, 2007, 06:46 PM
The following method will create and display every combination of characters from the specified array of the specified length:public void ListAllCombinations(char[] chars, int length)
{
int[] charIndexes = new int[length];
StringBuilder builder = new StringBuilder(length);
int index;
do
{
builder.Length = 0;
for (int i = 0; i < length; i++)
{
builder.Append(chars[charIndexes[i]]);
}
Console.WriteLine(builder.ToString());
index = length - 1;
do
{
charIndexes[index]++;
if (charIndexes[index]==chars.Length)
{
charIndexes[index] = 0;
index--;
}
else
{
break;
}
} while (index >= 0);
} while (index >= 0);
}It uses a single StringBuilder for all the strings it creates so there'll never be an issue with memory usage. If you want every combination of the characters 'a' to 'z' up to length 26 you would call it like this:char[] chars = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
for (int i = 1; i <= 26; i++)
{
this.ListAllCombinations(chars, i);
}Just be warned that that will take quite a long time. As I said before, if you want to be able to cancel it part way through you should use a BackgroundWorker. The more often you check for a pending cancellation the more immediate the result will be but also the more you'll slow down the process.
Fromethius
Feb 24th, 2007, 06:51 PM
you are the coolest person on this planet. i'll tell ya if it works, thanks a bunch
Fromethius
Feb 24th, 2007, 07:02 PM
wow john.. i love you no homo.. it works PERFECTLY
yea but thanks thanks thanks thanks thanks A LOT
jmcilhinney
Feb 24th, 2007, 07:06 PM
Cool. Here's the whole thing with explanatory comments and the multithreading. You'll just have to change the Console.WriteLine bit to do what you need.private void ListAllCombinations(char[] chars, int length, BackgroundWorker worker)
{
// The indexes of the chars that will make up the next string.
int[] charIndexes = new int[length];
// Use a single StringBuilder so that the same memory is used over and over.
StringBuilder builder = new StringBuilder(length);
// The index of the char index to be incremented.
int index;
do
{
// Clear the last string.
builder.Length = 0;
// Build a string using the chars at the current indexes.
for (int i = 0; i < length; i++)
{
builder.Append(chars[charIndexes[i]]);
}
// Display the string that was just built.
Console.WriteLine(builder.ToString());
if (worker.CancellationPending)
{
// The operation has been cancelled so end the loop.
break;
}
// Start incrementing char indexes with the last.
index = length - 1;
do
{
// Increment the current char index.
charIndexes[index]++;
if (charIndexes[index] == chars.Length)
{
// The current char index has gone past the last char so wrap back to the first char...
charIndexes[index] = 0;
// ...and start incrementing the previous char index.
index--;
}
else
{
break;
}
} while (index >= 0);
} while (index >= 0);
}
private void button1_Click(object sender, EventArgs e)
{
if (!this.backgroundWorker1.IsBusy)
{
// Start the long-running operation.
this.backgroundWorker1.RunWorkerAsync();
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
char[] chars = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
BackgroundWorker worker = (BackgroundWorker)sender;
for (int i = 1; i <= 26; i++)
{
if (worker.CancellationPending)
{
// The operation has been cancelled so end the loop.
break;
}
// Create all combinations of length i.
this.ListAllCombinations(chars, i, worker);
}
}
private void button2_Click(object sender, EventArgs e)
{
if (this.backgroundWorker1.IsBusy)
{
// Start the long-running operation.
this.backgroundWorker1.CancelAsync();
}
}Make sure you set the BackgroundWorker's WorkerSupportsCancellation property to True.
Fromethius
Feb 24th, 2007, 07:11 PM
umm.. just curious. would it be bad to just reset the program when i press f9 instead of using background workers?
Fromethius
Feb 24th, 2007, 07:24 PM
well i put in the background worker but i am getting this error:
http://server2.uploadit.org/files/Fromethius-error111.JPG
At this part:
// Display the string that was just built.
SendKeys.Send("{ENTER}");
SendKeys.Send("-" + builder.ToString());
SendKeys.Send("{ENTER}");
jmcilhinney
Feb 24th, 2007, 07:53 PM
The options would be to call the ReportProgress method and call Send from the ProgressChanged event handler, which is executed in the UI thread, or else do as the error message suggests and call SendWait instead.
Fromethius
Feb 24th, 2007, 07:56 PM
odd.. sendwait wasn't working but.. now it is.. w/e.. thanks again john :)
jmcilhinney
Feb 24th, 2007, 07:56 PM
umm.. just curious. would it be bad to just reset the program when i press f9 instead of using background workers?If your main thread is busy performing this long operation then it won't know that you've pressed F9 until it finishes, which is obvioulsy no help. The dodgy way around that is to call Application.DoEvents intermittently, but that is rather inefficient. The proper way around it is to use multithreading.
vbforums.com
Copyright Internet.com Inc., All Rights Reserved.