Exact Search, not partial [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
thanks everyone for your help, it gave me many ideas, and show me a lot o ways of using diferent functions or methods... this is my fourth day with C#, learning in home, with tutorials... the answer to this was like that
procs[i].ProcessNmae... is not a frase... but a LIST...
so i did this
public void chupala()
{
for (int i = 0; i < procs.Length; i++)
{
if (procs[i].ProcessName == "firefox") //that way it search for the EXACT match...
{
using (var player = new SoundPlayer("C:\\bass.wav"))
{
player.Play();
}
}
}
}
the public void chupala() is what i've created... the rest was downloaded, so it takes ALL running process... what i did is add that public void, so when I click the button IF firefox is open it will make a sound... the problem is that if a write "fire" it makes the sound too... i tested this WITH MY PROGRAM OPEN, close firefox... press the button... nothen happens... open firefox... click the button, the sound activates... but if i have another application that starts or contains the word fire it will make the sound anyway :s thats why i need it to find the EXACT match...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.Media;
namespace SimpleTaskManager
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Process[] procs;
public void GetProcesses()
{
procs = Process.GetProcesses();
if (Convert.ToInt32(label2.Text) != procs.Length) // Check if new processes have been started or terminated
{
listBox1.Items.Clear();
for (int i = 0; i < procs.Length; i++)
{
listBox1.Items.Add(procs[i].ProcessName); // Add the process name to the listbox
}
label2.Text = procs.Length.ToString();
}
}
public void chupala()
{
for (int i = 0; i < procs.Length; i++)
{
bool b;
b = (procs[i].ProcessName.Contains("fire"));
if (b)
{
using (SoundPlayer player = new SoundPlayer("C:\\bass.wav"))
{
player.Play();
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
GetProcesses();
}
// Check every 1 second for changes in the processes list
private void timer1_Tick(object sender, EventArgs e)
{
GetProcesses();
}
private void button1_Click(object sender, EventArgs e)
{
chupala();
// procs[listBox1.SelectedIndex].Kill(); // Kill the process coresponding to the selected index of listbox1
}
private void kIllProcessToolStripMenuItem_Click(object sender, EventArgs e)
{
procs[listBox1.SelectedIndex].Kill();
}
public void lsit()
{
}
}
}

Another way you can do this is to use a regex to search, and putting your search term between word boundarys \b:
// Returns false
Regex.IsMatch("The quick brown fox jumps over the lazy dog", #"\bfo\b")
// Returns true
Regex.IsMatch("The quick brown fox jumps over the lazy dog", #"\bfox\b")
You can read more about word boundaries here:
Simply put: \b allows you to perform a "whole words only" search using a regular expression in the form of \bword\b. A "word character" is a character that can be used to form words. All characters that are not "word characters" are "non-word characters".
Update because I got more info from original poster
Rewrite your chupala() method to use a Regex to do the search, instead of using the Contains method:
public void chupala()
{
for (int i = 0; i < procs.Length; i++)
{
if (Regex.IsMatch(procs[i].ProcessName, #"\bFirefox\b"))
{
using (var player = new SoundPlayer(#"C:\bass.wav"))
{
player.Play();
}
}
}
}

Perhaps not the fastest search, but here is what you can do
Split your input string by delimiter (in your case this is SPACE - s1.Split(" "))
Iterate over the result array
Check if s2 equals to any of the items in the array

Try This:
string s1 = "The quick brown fox jumps over the lazy dog";
string s2 = "fox";
bool b;
var words = s1.Split(' ');
foreach (var word in words)
{
b = word.Equals(s2);
if (b)
break;
}
Console.WriteLine("Is the string, s2, in the string, s1?: {0}", b);

MSDN :
The search begins at the first character position of this string and continues through the last character position.
This is a reason why you get the result True. if you want to search for exact string, you can Regex.
EDIT: I get an updated question
public void chupala()
{
for (int i = 0; i < procs.Length; i++)
{
bool b;
// Use Regex in here, assume that ProcessName of Firefox app is Firefox
b = Regex.IsMatch(procs[i].ProcessName, #"(^|\s)Firefox(/s|$)");
if (b)
{
using (SoundPlayer player = new SoundPlayer("C:\\bass.wav"))
{
player.Play();
}
}
}
}

Related

How do I convert Morse code to ASCII text

Yes this is homework but I have spent a few hours trying to figure it out. So right now I am doing a project in which you convert plain text into morse code, I was able to do so and it was relatively easy. However, now I need to convert the morse code back into text and I've run into a roadblock. I am not sure if I should make a new dictionary and reverse the text and char or if I should just reverse the existing dictionary that I have already made. Also we're not allowed to use if or case statements which makes it a bit harder but not by too much.
Here is what I have so far:
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Morse_Code_Converter
{
public partial class Form1 : Form
{
private Dictionary<char, String> morse = new Dictionary<char, String>()
{
{' ', " /" },{',', " --..--" }, {'.', " .-.-.-" }, {'?'," ..--.."},{'0'," -----"},{'1', " .----"},
{'2'," ..---"},{'3'," ...--"},{'4'," ....-"},{'5'," ....."},{'6'," -...."},{'7'," --..."},{'8'," ---.."},
{'9'," ----." },{'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'," --.."}
};
public Form1()
{
InitializeComponent();
}
private void convertToMorseButton_Click(object sender, EventArgs e)
{
string input = morseTextBox.Text;
var sb = new StringBuilder();
for (int index = 0; index < input.Length; index++)
{
var t = input[index];
input = input.ToLower();
string morseValue;
morse.TryGetValue(t, out morseValue);
sb.Append(morseValue);
}
textToMorseLabel.Text = sb.ToString();
}
private void morseToTextButton_Click(object sender, EventArgs e)
{
//This is where I want to convert
}
private void exitButton_Click(object sender, EventArgs e)
{
this.Close();
}
private void clearButton_Click(object sender, EventArgs e)
{
morseTextBox.Text = "";
}
private void morseClearButton_Click(object sender, EventArgs e)
{
textBox.Text = "";
}
}
}
If someone can help guide me in the right direction that would greatly appreciated.
Since this is a school project, I don't give you the code, but I will try to explain, how you can do it.
I suppose morse codes (in input) are separated by a space, so first use String.Split(' ') to get a string[] each with a morsecode string.
I also assume, that you're not familiar with 'Linq' (yet) - or are not allowed to use it, so now you iterate (with a for loop) through this array, then use a for loop to find the item in morses Dictionary that has the value equal to this morsecode and return the key.
Using this method you don't need an extra dictionary. However, if this was real code, you should create a reverse Dictionary, which is faster than this approach.

c# string iterator for showing words one by one [duplicate]

This question already has answers here:
WinForm Application UI Hangs during Long-Running Operation
(3 answers)
Closed 1 year ago.
What I want to do is a program that includes textbox (or something else that allows me to do it ) and this textbox is going to show the text from my resource .txt file and this is going to be like one word after another or two words after another for users to improve eye-movement on the text. To make it more clear the textbox is going to show the words two by two . I can do it by using string array but it only works on Listbox and Listbox is not okay for this project because it goes vertical and I need horizontal text like as we see in books.
And this is the code that shows the logic of what ı want but ı cannot use it it stops when I click the button.
{
public Form1()
{
InitializeComponent();
}
string[] kelimeler;
private void button1_Click(object sender, EventArgs e)
{
const char Separator = ' ';
kelimeler = Resource1.TextFile1.Split(Separator);
}
private void button2_Click(object sender, EventArgs e)
{
for (int i = 0; i< kelimeler.Length; i++)
{
textBox1.Text += kelimeler[i]+" " ;
Thread.Sleep(200);
}
}
}
Here's how to do it with async and await. It uses async void, which is generally frowned upon, but it's the only way I know how to make a button handler async.
I don't fish the starting string out of resources, I just do this:
private const string Saying = #"Now is the time for all good men to come to the aid of the party";
And, I carved of the retrieval and splitting of the string it's own function (that uses yield return to fabricate the enumerator).
private IEnumerable<string> GetWords()
{
var words = Saying.Split(' ');
foreach (var word in words)
{
yield return word;
}
}
Then all that's left is the code that sticks the words in the text box. This code does what I think you want (puts the first word in the text box, pauses slightly, puts the next, pauses, etc.).
private async void button3_Click(object sender, EventArgs e)
{
textBox4.Text = string.Empty;
foreach (var word in GetWords())
{
textBox4.Text += (word + ' ');
await Task.Delay(200);
}
}

Comparing string from label and input(textBox) and showing result in label. Plus operation on array

I'm writing a FlashCard app in Windows Form.
Right now I'm trying to do is read word from string array and pass it to label. Then asking user to write the translation of this word. And finally pass the result to label box.
Here is my code:
public partial class EnglishPolishScreen : Form
{
//English words array
string[] words = new string[] { "word1", "word2", "word3", "word4" };
// meanings words array
string[] wordB = new string[] { "slowo1", "slowo2", "slowo3", "slowo4" };
int element = 0;
Thread thread;
public EnglishPolishScreen()
{
InitializeComponent();
}
private void CloseAppEvent(object sender, FormClosingEventArgs e)
{
Application.Exit();
}
private void button1_Click(object sender, EventArgs e)
{
thread = new Thread(Threadd);
thread.Start();
}
private void Threadd()
{
englishWord.Text = words[element];
counterLabel.Text = element + 1 + " of " + words.Length;
if (answerBox.Text.Equals(wordB[element]))
{
resultLabel.Text = "Good";
element++;
}
else
resultLabel.Text = "Bad";
if (element == words.Length)
{
element = 0;
}
}
private void EnglishPolishScreen_Load(object sender, EventArgs e)
{
englishWord.Text = words[element];
}
Edited
Guys, Why I have to click two times in button to see next item from array? And why I can see "bad" answer straight after I click button? The "Good" answer shows up after second click.
Edited v2.xD
Sorted. Anyway is it good way to write code like this? If not how It could look better? Thanks
Regards
On button click, it is going through the whole for loop, i.e. the entire list of meanings, you would have to break the for loop as soon as a right match is found. So just use break; after resoultLabel.Text = "Good answer!";. Also as pointed out by #Neil, it is not good to use UI in a separate background thread.
By the way, I am not able to wrap my head around the logic of chances. For giving chances you would have to declare a global variable which would get added/subtracted when the a bad answer is found after Iterating through whole for loop, disallowing any further trial for the word.

Find all newlines in richtextbox

I am working on a custom texteditor control and encountered this problem.
I need a function that gets the character indexes for every newline "\n" in the text.
I already have two ways to accomplish this:
private List<int> GetNewLineLocations()
{
var list = new List<int>();
int ix = 0;
foreach (var c in this.Text)
{
if (c == '\n') list.Add(ix);
ix++;
}
Debug.WriteLine(ix);
return list;
}
And:
private List<int> GetNewLineLocations()
{
var list = new List<int>();
int ix = -1;
for (int i = 0; i < this.Lines.Length; i++)
{
ix += Lines[i].Length;
ix += 1;
list.Add(ix);
}
return list;
}
The first solution does work but slows down the more text is entered in the richtextbox that is around 40000 characters but that can be spread out among a lot of rows like 20000.
The second one seems to be faster because it loops less and does more or less the same but is slows down dramatically at 1000 rows no mater how much text they contain.
The code of course needs to run fast and not use a lot of resources that is why I thought the second solution would be better.
My question is:
Which solution is better and why?
Why is the second solution so much slower?
Is there an even better solution?
I tried both of your examples and Felix's and a solution of my own using a rich text box and 40k lines. The result was this was the fastest, and I saw no slow down. Can you try passing the array of lines as a paramater and let us know the result?
public static List<int> GetNewLineLocations(this string[] lines)
{
var list = new List<int>();
int ix = -1;
for (int i = 0; i < lines.Length; i++)
{
ix += lines[i].Length+1;
list.Add(ix);
}
return list;
}
When working with strings Regular Expressions are very nice to use. But they are not the fastest. If you need faster processing you should do it on lower levels and in parallel. And make sure to use long as index because int only allow you to process up to 2^31 chars, and long up to 2^63 chars.
I agree with #Nyerguds
who sayed in the comments:
The problem is that the standard function to fetch the text in a rich text box is actually a processing function that has to filter out the RTF markup. The actual function to fetch the text is the bottleneck, not what comes after it.
So your data should be held somewhere in the code and not in the userinterface. Sooner or later when processing long texts that will cause trouble anyway, like stuttering when scrolling or further bottlenecks. And I would only represent the lines that could be displayed in the control anyway. So you should overthink your application design. Check your Front/Backend seperation. Storing your data in a backend will allow you to access your data directly without depending in your Textbox methods or other userinterface stuff.
Here is a sample how to easy process data with the Parallel Class of the .net framework:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
internal class Program
{
public static byte[] _globalDataStore { get; set; }
private static void Main(string[] args)
{
DoStuff();
ShowDone();
}
private static void ShowDone()
{
Console.WriteLine("done...");
Console.ReadKey();
}
private static void DoStuff()
{
var tempData = GetData();
StoreData(ref tempData);
tempData = null; //free some ram
var dataIdentifier = (byte)'\n';
GetAndPromptDataPositions(_globalDataStore, dataIdentifier);
}
private static void GetAndPromptDataPositions<T>(T[] data, T dataIdentifier)
{
var dataPositionList = GetDataPositions<T>(data, dataIdentifier);
PromptDataPostions(dataPositionList);
}
private static void PromptDataPostions(IEnumerable<long> positionList)
{
foreach (var position in positionList)
{
Console.WriteLine($"Position '{position}'");
}
}
private static string GetData()
{
return "aasdlj\naksdlkajsdlkasldj\nasld\njkalskdjasldjlasd";
}
private static void StoreData(ref string tempData)
{
_globalDataStore = Encoding.ASCII.GetBytes(tempData);
}
private static List<long> GetDataPositions<T>(T[] data, T dataToFind)
{
lock (data) //prevent data from being changed while processing, important when have other threaded could write data
{
var postitonList = new List<long>();
Parallel.For(0, data.LongLength, (position) =>
{
if (data[position].Equals(dataToFind))
{
lock (postitonList) //lock list because of multithreaded access to prevent data corruption
{
postitonList.Add(position);
}
}
});
return postitonList;
}
}
}
}

Windows form application - C# Random numer guessing game

I need a little help with a Random Number Guessing Game in visual studio. I got the brunt of the code down but I am having troubles with the Random number generator and getting the random number to port into the click events. As always, I don't really need code but some guidance and/or explanations as to what I am doing wrong and if there is a more effecient way to do things in the beginner phases of learning. Below is my code, the comments are the parts where I am having troubles. Thanks for any help as the help I've recieved to date as been phenominal.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace LAB6B
{
public partial class game : Form
{
public game()
{
InitializeComponent();
//Generate Random number between 1 and 100
//Not sure if there is a better way?
Random rand1 = new Random();
int num1 = rand1.Next(1,50);
int num2 = rand1.Next(1,50);
int answer = num1 + num2;
}
private void evaluate_Click(object sender, EventArgs e)
{
int count = 0;
int choice = Convert.ToInt32(guess);
if (guess.Text != string.Empty)
{
// set counter to keep track of how many tries
// should this be done by a loop or will it count without a loop?
count++;
//compare user input against random number
//Can’t import the random number for comparision
if (choice < answer)
{
Evaluate.Visible = false;
lblMessage.Visible = true;
lblMessage.Text = "Too Low!";
Clear.Visible = true;
BackColor = Color.LightSeaGreen;
}
else if (choice > answer)
{
Evaluate.Visible = false;
lblMessage.Visible = true;
lblMessage.Text = "Too High!";
Clear.Visible = true;
BackColor = Color.SlateBlue;
}
else
{
//Display correct message along with how many times it took to get it
MessageBox.Show(" Eso es CORRECTO! It took you {0} tries. ", count);
}
}
}
private void Clear_Click(object sender, EventArgs e)
{
guess.Text = "";
Evaluate.Visible = true;
lblMessage.Visible = false;
Clear.Visible = false;
BackColor = Color.PowderBlue;
}
}
}
As the rand1 and answer variables are defined within the constructor, you can only access them in the constructor. Defining answer on the class level will solve most of the problems, as you will be able to access it both from the constructor and the click handlers, like this:
private int answer;
private int count;
public game()
{
InitializeComponent();
//Generate Random number between 1 and 100
Random random= new Random();
// no need for num1 and num2, it's just as random
answer = random.Next(1,101);
}
I think you have an issue of scope. The "answer" variable is declared inside your constructor, so it will not be visible to the code inside evaluate_Click(…).
Looks like you need to declare answer as a class variable. When you declare a variable in a constructor, it's still local to that method and not available to other methods.
I do not really know what you want answered, but an obvious error is that you must define your count variable as a member variable in order to keep track of the number of tries. As it is now, the count will always be initialized as zero each time the user presses the button.
First of, you need to declare your variable answer in the page level so it can be used by other page level functions.
Do it like this
public partial class game : Form
{
int answer;
public game()
{
}
}
in your counter you can use a static counter or a page level variable also such as the variable answer
just reset the counter when the user have guessed correctly

Categories