C# WinForm: Select specific words and change colour - winforms

I have a program that allows the user to enter text, and it will highlight any repeat words. It already adds repeated words to one list and all the words to another. I want the program to print out the words, and if a repeat word is used, to highlight it.
I have tried using outputBox.Find(repeatList[i]) with a loop, but this only finds the first word used in the text. I also tried marking the current number for the last letter typed, selecting that point, finding the coordinates after the word.Length was typed, and then changing the colour of that, which didn't work.
for (int h = 0; h < repeatList.Count; h++)
{
for (int c = 0; c < repeatList.Count; c++)
{
outputBox.Find(repeatList[h]);
outputBox.SelectionColor = Color.Red;
}
}
At this point in the code, the outputBox already contains the users input, I just want to know how to compare words and select them for colouring. I've only just started Winforms and have only been coding for a few weeks, so I am sorry - I have looked at other answers but was not able to implement them. Thank you in advance for any responses.
EDIT: I would just like to add that my prefered method for colouring the text would be as it prints each word out, this was my original intention as I'm much more used to console applications where I can just change the colour and print more. If that method is easier to do than checking afterwards, I'm find to do that.

I would use the start index and keep a copy of it.
int startFrom = 0
...
startFrom = outputBox.Find(repeatList[h], startFrom)
You could then use the 'startFrom' index with the text word length to select the text.
Here is an example:
var findText = "test";
int index = 0;
do
{
index = richTextBox1.Find(findText, index, RichTextBoxFinds.WholeWord);
if (index > -1)
{
richTextBox1.Select(index, findText.Length);
richTextBox1.SelectionColor = Color.Red;
index++;
}
} while (index > -1);

Related

How to check the elements of a row in a 2D Array

So, what I am trying to do is a three in a row game, and so far I have managed to make it work, but I am struggling a bit when it comes to getting a winner, since I need to check that all the elements of either a row, a column or a diagonal are the same.
So far I have managed to get it to kinda work by using a boolean, a counter and a for loop. Here is an example of how my code looks
//Code to check the rows horizontally
public void checkH(){
int cont1 = 0;
Boolean winner1 = false;
for(int i=0;i<size;i++){
if(a[0][i]==1 || a[1][i]==1 || a[2][i]==1){
cont1++;
if(cont1==3){
winner1 = true;
}
So, as y'all can see what I am doing in that code is telling the program that if the array in either one of the rows is equal to one and if that same case happens when it goes through all the positions in the row, then the counter is going to add plus one, and once the counter hits 3, the boolean will be true and there will be a winner, but here is the catch: if, for example, the 2D array looks like this:
int a[][] = {{1,0,0},
{1,1,0},
{0,0,0}};
then the counter is still hitting three, even though they are not aligned. I know I havent specified that kind of condition in the program, but that's what I am struggling with. What I would like to do is to be able to make that condition with loops, so that I dont have to fill the whole thing with if statements.
Any leads you guys could give me on this would be highly appreciated. Thanks in advance!
If you are finding it difficult to search for a solution/tutorial on the web, notice that the three in a row game is also called tic-tac-toe. So, if you search for "tic tac toe algorithm" you will find several examples on how to solve it, as it is a somewhat usual interview question. Here is a reference for the reader’s convenience.
Now, for the desire to use for loops instead of chained ifs (or an if with multiple logical comparisons), it is a question about row-wise, column-wise and diagonal-wise traversal of a matrix. Here is a reference for the row and column traversals, and here is another reference for the diagonal traversal.
Specific to your question, below is a pseudo-code showing the check for column and row using for and the cell values to have a small number of if statements. But please notice this is just an example, as there are many interesting ways to solve a tic-tac-toe game that you may want to take a look, from traversing trees to using a string and regex.
public bool checkRow() {
int i, j;
int count = 0;
// accessing element row wise
for (i = 0; i < MAX; i++) {
for (j = 0; j < MAX; j++) {
// Considering we were checking for 1
// And array can have 0 or 1
// You can add the cell value and avoid an if
count += arr[i][j];
// if you go with arr[j][i] you will be traversing the columns and not the rows.
}
// if all cells in the row are 1, we have a winner
if(count == MAX)
return true;
}
return false
}

Should be easy array situation

My question shouldn't be too difficult but I haven't solved it yet. Basically, what I'm trying to do is to take a message (like this one), preserve each letter in the message, but generate a random message using each letter. So, I can currently read into a textbox (say) "Hello!", but I need to take the message in that textbox and (on the click of a button) have something like "lolH!e". There's got to be a simple way to read each letter into an array (or list, or whatever), and spit them out at random, but while using each letter only once as in the original message. Any thoughts?
In JavaScript you can do something like this:
function randomize(s){
var a = Array.from(s);
for(var j, x, i = a.length; i; j = parseInt(Math.random() * i), x = a[--i], a[i] = a[j], a[j] = x);
return a.join("");
}
Then use it like:
randomize("Hello!")
There are some other good solutions here: How do I shuffle the characters in a string in JavaScript?

How can i check if a word is in dictionary taking the user input that inserted into the array

I've been trying to figure out, the best way to tackle this problem.
The problem Im stuck on is where I need to take the user input(word) and put it in the array and try to confirm/validate if all the letters they've use are in the char array(generates 10 random letters)(letterpool) then check again if the word they've use are valid from the dictionary.
I have a dictionary called "dict.txt" which contains 80k words in lowercase
dictionary. i need somehow take the input(uppercase) and be able to locate the word of the dictionary in lowercase
I hope you guys can help me, Programming language Java
Thanks in advance!
Eric
I'd create a HashMap<Character, Integer> and put the random letters in the map.
map.put(letter, 0);
Then I'd go through the letters from your word and do this
Integer value = map.get(letterFromYourWord);
if(value == null){
//raise exception because the letter from your word is not in your random array
} else {
// increment the value from the map
map.put(letterFromYourWord, value++);
}
then go through the map and check if the values are not 0. If there is one with value 0 then your word is not used in your random array.
with this implementation you can extend easily more functionalities, like counting the letters which are used in your word...
For the validWord function I would suggest making use of the binary search for sorted arrays. Something along those lines:
static boolean validWord(String word, final char[] letters)
{
char[] lettersCopy = letters.clone();
Arrays.sort(lettersCopy); // sort so we can use binary search
for(char c : word.toCharArray())
{
if(Arrays.binarySearch(lettersCopy, c) < 0) //char c from word not in letterPool?
{
return false;
}
}
return true;
}
Then in your TRIALS loop you would just call it like this:
if (validWord(input,letterPool))
{
System.out.println("Yes, the letters match");
}else {
System.out.println("No");
}
I am not sure which Dictionary class you are using there so I cannot help you with that.
Btw:
Arctigors answer using hashmaps is more cpu performant yet more heavy on the memory side. (O(n) instead of O(n*lb(m)))

AS3 make an array of movieclip moves constantly. (this array constantly increases in size)

ActionScript 3.0
I got this bullet_array.
and it pushes new bullet everytime I pressed spacebar.
There's this "for loop", which works - only when I pressed spacebar.
but I wanted the bullets to constantly move.
the 'for loop' is inside update(), which is from Event.ENTER_FRAME
so technically, the for loop should constantly be looping (i think), but it only went through ONCE, and only after the array increases in size. And it only worked on the new object, and didn't touch the old object.
public function update(evt:Event = null)
{
stage.focus = stage;
//fire = true is set by spacebar
if (fire == true)
{
var snowball:MovieClip = new Snowball;
snowball.x = (mcPlayer.x);
snowball.y = (mcPlayer.y - 5);
snowballArray.push(snowball);
SBAlength = +1; //stands for snowballArray's length
addChild(snowball);
fire = false;
}
for (var i = SBAlength - 1; i >= 0; i--)
{
snowballArray[i].y -= snowballSpd; //snowballSpd is already declared as 5
for (var j = snowmanArray.length - 1; j>=0; j--)
{
for (var k = numberArray.length -1; k>0; k--)
{
if (snowballArray[i].hitTestObject(snowmanArray[j]))
{
if (snowmanArray[j].hitTestObject(numberArray[k]))
{
bosslife -= numberArray[k];
numberArray[k].splice(k,1);
}
snowballArray[i].gotoAndPlay("hit");
snowmanArray[j].splice(j,1);
break;
}
if(numberArray[k] >= 0)
{
numberArray[k].splice(k,1);
randomNo= Math.floor(Math.random()*(max-min+1))+min;
numberArray[k].push(randomNo);
}
snowmanArray[j].txtNumber.text = numberArray[j];
}
}
There may be other issues here, but:
Maintaining the array length
SBAlength = +1; // Sets your length to 1
Instead use:
SBAlength += 1; // Increases your length by 1
But really, you might as well use the array's length property in the loop, instead of maintaining SBALength (and risking it getting out of sync due to some future code):
for (var i = snowballArray.length - 1; i >= 0; i--)
Manipulating arrays
Also (don't think this is related to your problem, but it will certainly cause errors), in your inner loop, you're constantly doing things like this:
snowmanArray[j].splice(j,1);
numberArray[k].push(randomNo);
// etc.
That would only work if the items in numberArray and snowmanArray are themselves arrays - not sure if they are, but doesn't seem like it, since you're also using the items as numbers:
bosslife -= numberArray[k];
The first statement is asking to remove an item from an array stored in snowmanArray[j] - not removing an item from snowmanArray itself. If you want to remove an item from snowmanArray, you'd do snowmanArray.splice(j, 1).
In the same way, to add an item to numberArray, you'd do numberArray.push(randomNo), rather than numberArray[k].push(randomNo).
Manipulating arrays inside loops etc.
It's fine to e.g. remove the current array item while iterating over that array - but only as long as you do it in the way you do, starting from the end and going backwards. However...
After doing (or rather, intending to do) this if the snowman was hit:
snowmanArray.splice(j,1);
... you're later doing:
snowmanArray[j].txtNumber.text = numberArray[j];
I.e. you remove the snowman from the array, but then later on, you try to get the array item you just removed. You need to be sure that snowmanArray[j] still exists before you address it.
Array item types
You're mostly using numberArray as an array of int (or Number). Except here:
snowmanArray[j].hitTestObject(numberArray[k])
You can't hitTestObject against an int/Number. Not sure what the line is supposed to do, but the object you hit test against needs to be a DisplayObject (e.g. a MovieClip).
Erm... after lots of tracing around and stuff,
i figure that the main problem isn't with the array nor the splicing (though my codes is wrong -but it didn't work even if i commented away those codes), but that i place > instead of < to check bosslife, so it keep resetting the level, so snowballArray keeps becoming a new Array, hence the array.length didn't work, and using SBAlength gives some kinda weird error while inside the for loop.

How do I remove duplicate strings from an array in C?

I have an array of strings in C and an integer indicating how many strings are in the array.
char *strarray[MAX];
int strcount;
In this array, the highest index (where 10 is higher than 0) is the most recent item added and the lowest index is the most distant item added. The order of items within the array matters.
I need a quick way to check the array for duplicates, remove all but the highest index duplicate, and collapse the array.
For example:
strarray[0] = "Line 1";
strarray[1] = "Line 2";
strarray[2] = "Line 3";
strarray[3] = "Line 2";
strarray[4] = "Line 4";
would become:
strarray[0] = "Line 1";
strarray[1] = "Line 3";
strarray[2] = "Line 2";
strarray[3] = "Line 4";
Index 1 of the original array was removed and indexes 2, 3, and 4 slid downwards to fill the gap.
I have one idea of how to do it. It is untested and I am currently attempting to code it but just from my faint understanding, I am sure this is a horrendous algorithm.
The algorithm presented below would be ran every time a new string is added to the strarray.
For the interest of showing that I am trying, I will include my proposed algorithm below:
Search entire strarray for match to str
If no match, do nothing
If match found, put str in strarray
Now we have a strarray with a max of 1 duplicate entry
Add highest index strarray string to lowest index of temporary string array
Continue downwards into strarray and check each element
If duplicate found, skip it
If not, add it to the next highest index of the temporary string array
Reverse temporary string array and copy to strarray
Once again, this is untested (I am currently implementing it now). I just hope someone out there will have a much better solution.
The order of items is important and the code must utilize the C language (not C++). The lowest index duplicates should be removed and the single highest index kept.
Thank you!
The typical efficient unique function is to:
Sort the given array.
Verify that consecutive runs of the same item are setup so that only one remains.
I believe you can use qsort in combination with strcmp to accomplish the first part; writing an efficient remove would be all on you though.
Unfortunately I don't have specific ideas here; this is kind of a grey area for me because I'm usually using C++, where this would be a simple:
std::vector<std::string> src;
std::sort(src.begin(), src.end());
src.remove(std::unique(src.begin(), src.end()), src.end);
I know you can't use C++, but the implementation should essentially be the same.
Because you need to save the original order, you can have something like:
typedef struct
{
int originalPosition;
char * string;
} tempUniqueEntry;
Do your first sort with respect to string, remove unique sets of elements on the sorted set, then resort with respect to originalPosition. This way you still get O(n lg n) performance, yet you don't lose the original order.
EDIT2:
Simple C implementation example of std::unique:
tempUniqueEntry* unique ( tempUniqueEntry * first, tempUniqueEntry * last )
{
tempUniqueEntry *result=first;
while (++first != last)
{
if (strcmp(result->string,first->string))
*(++result)=*first;
}
return ++result;
}
I don't quite understand your proposed algorithm (I don't understand what it means to add a string to an index in step 5), but what I would do is:
unsigned int i;
for (i = n; i > 0; i--)
{
unsigned int j;
if (strarray[i - 1] == NULL)
{
continue;
}
for (j = i - 1; j > 0; j--)
{
if (strcmp(strarray[i - 1], strarray[j - 1]) == 0)
{
strarray[j - 1] = NULL;
}
}
}
Then you just need to filter the null pointers out of your array (which I'll leave as an exercise).
A different approach would be to iterate backwards over the array and to insert each item into a (balanced) binary search tree as you go. If the item is already in the binary search tree, flag the array item (such as setting the array element to NULL) and move on. When you've processed the entire array, filter out the flagged elements as before. This would have slightly more overhead and would consume more space, but its running time would be O(n log n) instead of O(n^2).
Can you control the input as it is going into the array? If so, just do something like this:
int addToArray(const char * toadd, char * strarray[], int strcount)
{
const int toaddlen = strlen(toadd);
// Add new string to end.
// Remember to add one for the \0 terminator.
strarray[strcount] = malloc(sizeof(char) * (toaddlen + 1));
strncpy(strarray[strcount], toadd, toaddlen + 1);
// Search for a duplicate.
// Note that we are cutting the new array short by one.
for(int i = 0; i < strcount; ++i)
{
if (strncmp(strarray[i], toaddlen + 1) == 0)
{
// Found duplicate.
// Remove it and compact.
// Note use of new array size here.
free(strarray[i]);
for(int k = i + 1; k < strcount + 1; ++k)
strarray[i] = strarray[k];
strarray[strcount] = null;
return strcount;
}
}
// No duplicate found.
return (strcount + 1);
}
You can always use the above function looping over the elements of an existing array, building a new array without duplicates.
PS: If you are doing this type of operation a lot, you should move away from an array as your storage structure, and used a linked list instead. They are much more efficient for removing elements from a location other than the end.
Sort the array with an algorithm like qsort (man 3 qsort in the terminal to see how it should be used) and then use the function strcmp to compare the strings and find duplicates
If you want to mantain the original order you could use a O(N^2) complexity algorithm nesting two for, the first each time pick an element to compare to the other and the second for will be used to scan the rest of the array to find if the chosen element is a duplicate.

Resources