Reputation: 75
I have a WPF application which has 2 textboxes with one of them being filled with a ciphered text (from a txt file) and one of them being filled with a reference text (also from a txt file). I have to count the number of times each character of the alphabet repeats in both texts and just switch the characters, so the ciphered text would be deciphered.
Now I have to switch the characters where the number of repetitions in both texts are the same (or if it's the same number of repetitions, just take the first one) and apply that to the ciphered textbox (so when I would click on the decipher button, it would change the letters in the textbox).
Here is the code I have so far:
public partial class MainWindow : Window
{
public static SortedDictionary<char, int> Count(string stringToCount)
{
SortedDictionary<char, int> characterCount = new SortedDictionary<char, int>();
foreach (var character in stringToCount)
{
int counter = 0;
characterCount.TryGetValue(character, out counter);
characterCount[character] = counter + 1;
}
return characterCount;
}
public MainWindow()
{
InitializeComponent();
}
private void button2_Click(object sender, RoutedEventArgs ex) //Decipher button
{
var ciphered = Count(textBox.Text);
var referenced = Count(textBox1.Text);
var deciphered= "";
foreach (var val in ciphered)
{
foreach (var x in referenced)
{
if (val.Value == x.Value)
{
deciphered = textBox.Text.Replace(val.Key.ToString(), x.Key.ToString());
}
}
}
textBox.Text = deciphered;
}
}
The above code "kind of" works, but I have to press the button multiple times, when it should be done in one click.
All help would be much appreciated!
Upvotes: 2
Views: 158
Reputation: 2970
I think you are iterating over the wrong thing. You want to replace every char once, so you should iterate over every char once :)
There are multiple ways of doing this. Here it is one that i used once in an introduction to programming class.I believe it is easier to understand, but not the most efficient:
// A dictionary that for every char, it indicates what should be the replacement
Dictionary <char, char> Replacements = .... // I think you know how to do this :)
// Iterate over every char, so you never change the same char twice
for(int position = 0; position < ciphered.Lenght; position++)
{
ciphered[position] = Replacement[ciphered[position]];
}
Upvotes: 1
Reputation: 17027
Your program is correct, but your logic is not, i explain:
for example you have the same counter for 'x' and 'o'.
first, x is replaced by o
but further in loop, you replace o by x... so final operation is null..
you have changes only if you have at least 3 char with same counter
and when you click more times, you see the result for your little modification
to avoid this problem you could repeat x times the processus: (here i choose the loop for 10 times) just modify the button2_click
private void button2_Click(object sender, RoutedEventArgs ex) //Decipher button
{
var deciphered = "";
// loop to repeat the processus
for (int i = 0; i < 10; i++)
{
var ciphered = Count(textBox.Text);
var referenced = Count(textBox1.Text);
foreach (var val in ciphered)
{
foreach (var x in referenced)
{
if (val.Value == x.Value && val.Key != x.Key)
{
deciphered = textBox.Text.Replace(val.Key.ToString(), x.Key.ToString());
}
}
}
textBox.Text = deciphered;
}
}
Upvotes: 0