Extract text from caret position textarea - wpf

I am having trouble to extract text from textarea using WPF code behind.
Example:
Sunny day in London
if the cursor is set on [d*ay] it should return day.
* for the cursor.
Any help will be appreciated.

This seems to work but I am not sure how you want it to behave when the caret is in the middle of whitespace. As is, it basically returns the nearest token that is touching the caret. For example, the phrase "Sunny day in London" has four tokens: "Sunny", "day", "in", and "London".
string selection;
if (txtBox.Text.Length > 0)
{
int startIndex = 0;
for (int i = txtBox.CaretIndex - 1; i >= 0; i--)
{
if (String.IsNullOrWhiteSpace(txtBox.Text[i].ToString()))
{
startIndex = i;
break;
}
}
int length = txtBox.Text.Length - startIndex;
for (int i = startIndex; startIndex + i <= txtBox.Text.Length - 1; i++)
{
if (String.IsNullOrWhiteSpace(txtBox.Text[startIndex + i].ToString()))
{
length = i;
break;
}
}
selection = txtBox.Text.Substring(startIndex, length);
}
else
{
selection = "";
}

Related

Searching for block of characters (word) in a text

I want to search for a block of characters (word) in a text.
For example, I have the next text "Hello xyz world", and I want to search for "xyz ", note the space after the word.
// The Text
const char * text = "Hello xyz world";
// The target word
const char * patt = "xyz ";
size_t textLen = strlen(text),
pattLen = strlen(patt), i, j;
for (i = 0; i < textLen; i++) {
printf("%c", text[i]);
for (j = 0; j < pattLen; j++) {
if (text[i] == patt[j]) {
printf(" <--");
break;
}
}
printf("\n");
}
The result must be like following:
But unfortunately, the result as the following:
It collects all the similar characters in the whole text, not just the target characters (the word).
How to fix that problem?
You have to do a full substring match before you print; mark the applicable characters on a first pass, and then have a second pass to print the results. In your case, you'd create a second array, with boolean values corresponding to the first, something like
text = "Hello xyz world";
match 000000111100000
I assume that you can find a basic substring match program online. Printing on the second pass will be easy: you already have the logic. Instead of if (text[i] == patt[j]), just use if match[i].
Is that enough of a hint?
You need to make sure that there is a full match before starting to print any <--. And to avoid to do accesses passed end of array on patt, you will have to stop searching when less than pattLen characters remain in array.
Then when you have found a full match, you can print the content of patt followed with <-- and increment position of pointer of pattLen-1. And at the end you will have to copy remaining characters from text.
Code could become:
// The Text
const char * text = "Hello xyz world";
// The target word
const char * patt = "xyz ";
size_t textLen = strlen(text),
pattLen = strlen(patt), i, j;
for (i = 0; i <= textLen - pattLen; i++) { // don't search if less that pattLen remains
printf("%c", text[i]);
if (text[i] == patt[0]) { // first char matches
int found = 1; // be optimistic...
for (j = 1; j < pattLen; j++) {
if (patt[j] != text[i + j]) {
found = 0;
break; // does not fully match, go on
}
}
if (found) { // yeah, a full match!
printf(" <--"); // already printed first char
for (j = 1; j < pattLen; j++) {
printf("\n%c <--", patt[j]);// print all others chars from patt
}
i += pattLen - 1; // increase index...
}
}
printf("\n");
}
while (i < textLen) {
printf("%c\n", text[i++]); // process the end of text
}
Above code gives expected output for "xyz " and also "llo"...
You should check every letter of your pattern from the beginning (and not check the whole pattern). Try this (not tested):
int currIndex = 0;
for (i = 0; i < textLen; i++) {
printf("%c", text[i]);
if (text[i] == patt[currIndex]) {
for (j = 0; j < pattLen; j++) {
if(text[i+j] != patt[j]){
continue;
}
}
printf(" <--");
currIndex++;
if(currIndex==pattLen)
currIndex = 0;
}
else{
currIndex = 0;
}
printf("\n");
}
Note: It is not the best way to achieve this but the easiest with your example
Note 2: This question should be closed as it is:
Questions seeking debugging help ("why isn't this code working?") must
include the desired behavior, a specific problem or error and the
shortest code necessary to reproduce it in the question itself.
Questions without a clear problem statement are not useful to other
readers. See: How to create a Minimal, Complete, and Verifiable
example.

How to check for n consecutive same characters in row in c

So my assignment is to write a program for Connect-N, which is basically the game Connect-4 but where the user specifies the number of rows and columns (doesn't have to be square) and specifies the number of consecutive pieces to win (this doesn't have to fit on the board). For example, if the user specifies a 3x3 board, they can also say 4 consecutive pieces are needed to win.
I'm having trouble writing a program to check for a row win, where the player wins the game completely horizontally. Here's what I have so far:
bool horizontalWin(char **board, const int numRows,
const int numCols, const char blankSpace, const int numToWin) {
if((numCols - numToWin) < 0) {
return false;
}
else {
for (int row = 0; row < numRows; ++row) {
for (int col = 0; col <= numCols-numToWin; ++col) {
///This is where I need help
}
}
}
return false;
}
Just for reference: the variable blankSpace is a '*' and is used to denote a blank space on the board.
My idea was to have a nested for loop that started at column 0 and then checked far enough forward to see if they were all identical characters, but I can't seem to figure out how to accomplish this. Can someone point me in the right direction?
Count the number of matches, or reset the count when there is no match.
Assuming board[row][col], and that the color you check is user1
for (int row = 0; row < numRows; ++row) {
int match = 0;
for (int col = 0; col <= numCols-numToWin; ++col) {
if (board[row][col] != user1) match = 0;
else {
match++;
if (match >= numToWin) return true;
}
}
}
Note that you could do if (++match >= numToWin) return true; to save a line (if you feel this being readable).
This is not in the problem description, but if you have two players, there should be 3 colors, say blankSpace, user1, and user2. The program above checks if user1 wins.
So you could add an argument to the function to tell which color you are testing for a win (say colorCheck), the whole function becomes
bool horizontalWin(char **board, const int numRows,
const int numCols, const char blankSpace, const int numToWin, const in colorCheck) {
if((numCols - numToWin) < 0) {
return false;
}
else {
for (int row = 0; row < numRows; ++row) {
for (int col = 0; col <= numCols-numToWin; ++col) {
if (board[row][col] != colorCheck) match = 0;
else {
match++;
if (match >= numToWin) return true;
}
}
}
}
return false;
}
You can set two counters, one for the red discs and the other for the yellow ones. Then inside the body of your nested loop whenever you encounter an r increment the red discs counter by one, the same goes for yellow disks.
Then you can check after each row iteration if any of these counters equals the given N required to win the game.
You can do it this way supposing you denote a red disk with an r and a yellow disk with a y :
else
{
int red_c, yellow_c;
for (int row = 0; row < numRows; ++row)
{
red_c=0; yellow_c=0;
for (int col = 0; col < numCols; ++col)
{
if(board[r][c]=='r') red_c++;
else if (board[r][c]=='y') yellow_c++;
if(red_c == numToWin )
{
//Red wins
}
else if(yellow_c == numToWin )
{
//Yellow wins
}
}
}
}
The code will depend if you want to know if someone win in the board of if you win after an specific move.
This is a common and simple code that you can execute after each move or for every position in the board:
The idea is to move in every direction from the center (the new position of a piece) making something like a star " * " (like the star character)
consecutivesInHorizontal =0
consecutivesInVertical = 0
consecutivesDiagLeft =0
consecutiveDiagRight = 0
for i =1 ; i < height && i<width && i<= 4 ; i++
if(board[centerX][centerY+i] == myPieceColor)
consecutivesInVertical++;
if(board[centerX][centerY-i] == myPieceColor)
consecutivesInVertical++;
if(board[centerX+i][centerY] == myPieceColor)
consecutivesInHorizontal++;
if(board[centerX-i][centerY] == myPieceColor)
consecutivesInHorizontal++;
if(board[centerX+i][centerY-i] == myPieceColor)
consecutivesDiagLeft++;
if(board[centerX-i][centerY+i] == myPieceColor)
consecutivesDiagLeft++;
if(board[centerX-i][centerY+i] == myPieceColor)
consecutiveDiagRight++;
if(board[centerX+i][centerY-i] == myPieceColor)
consecutiveDiagRight
if any of the consecutive variables == 4
return true

Issue with displaying vertical and diagonal letters - C Programming

I'm totally new to C Programming and I'm trying to create a Word Search .
I've got a list of words , where only 4 are randomly picked. These 4 words than are to be printed in a grid horizontally, vertically or diagonally, however I can only get them to print horizontally. I also must add that I have no idea on how the piece of code works so I really appreciate if someone kind enough can actually help me. So can anybody help me in the right direction to create the random words in a vertical and diagonal alignment ?
http://imgur.com/VSrXf4C
void putHorizzontalWord(char word[10])
{
int rRow, rCol , ok , i;
do
{
rRow = rand() % 10;
rCol = rand() % 10;
ok = 1;
if(rCol + strlen(word) < 10)
{
for(i = 0;i < strlen(word);i++)
{
if(puzzle[rRow][rCol + i] == ' ' ||
puzzle[rRow][rCol + i] == word[i])
{
puzzle[rRow][rCol + i] = word[i];
}
else
{
ok = 0;
}
}
}
else
{
ok = 0;
}
}
while(ok == 0);
}
Here are some comments aimed to explain you what does that code does:
// This function takes a string as input then puts that string
// at a random "open" location in a 2D grid (puzzle) in an
// horizontal manner
//
// This function expects the size of the string to be at most = 10
void putHorizontalWord(char word[10])
{
int rRow, rCol , ok , i;
do
{
// Randomly select a location
rRow = rand() % 10;
rCol = rand() % 10;
// For now, assume that this location is "ok", i.e. is open
ok = 1;
// Check that the word fits inside the grid from (rRow, rCol)
if(rCol + strlen(word) < 10)
{
// If it does, then try to put the word at this location
// Thus, we need to process the word character by character
for(i = 0;i < strlen(word);i++)
{
// We are inside the for loop
// The current character to process is word[i]
// And the current cell to fill is (rRow, rCol + i)
//
// If current cell is empty || is same as the current character
// then this cell is "open" i.e. we can use it
if(puzzle[rRow][rCol + i] == ' ' ||
puzzle[rRow][rCol + i] == word[i])
{
puzzle[rRow][rCol + i] = word[i];
}
else
{
// The cell is not open
// => (rRow, rCol) is not "ok"
ok = 0;
}
}
}
else
{
// word not fits inside the grid from the location
// => (rRow, rCol) is not "ok"
ok = 0;
}
}
while(ok == 0); // Exit loop while not found a good location
}
If you have understood, then you can now modify this to write your vertical and diagonal versions. If you still have not understood, let me know what is still not clear.

code accounting for multiple delimiters isn't working

I have a program I wrote to take a string of words and, based on the delimiter that appears, separate each word and add it to an array.
I've adjusted it to account for either a ' ' , '.' or '.'. Now the goal is to adjust for multiple delimiters appearing together (as in "the dog,,,was walking") and still only add the word. While my program works, and it doesn't print out extra delimiters, every time it encounters additional delimiters, it includes a space in the output instead of ignoring them.
int main(int argc, const char * argv[]) {
char *givenString = "USA,Canada,Mexico,Bermuda,Grenada,Belize";
int stringCharCount;
//get length of string to allocate enough memory for array
for (int i = 0; i < 1000; i++) {
if (givenString[i] == '\0') {
break;
}
else {
stringCharCount++;
}
}
// counting # of commas in the original string
int commaCount = 1;
for (int i = 0; i < stringCharCount; i++) {
if (givenString[i] == ',' || givenString[i] == '.' || givenString[i] == ' ') {
commaCount++;
}
}
//declare blank Array that is the length of commas (which is the number of elements in the original string)
//char *finalArray[commaCount];
int z = 0;
char *finalArray[commaCount] ;
char *wordFiller = malloc(stringCharCount);
int j = 0;
char current = ' ';
for (int i = 0; i <= stringCharCount; i++) {
if (((givenString[i] == ',' || givenString[i] == '\0' || givenString[i] == ',' || givenString[i] == ' ') && (current != (' ' | '.' | ',')))) {
finalArray[z] = wordFiller;
wordFiller = malloc(stringCharCount);
j=0;
z++;
current = givenString[i];
}
else {
wordFiller[j++] = givenString[i];
}
}
for (int i = 0; i < commaCount; i++) {
printf("%s\n", finalArray[i]);
}
return 0;
}
This program took me hours and hours to get together (with help from more experienced developers) and I can't help but get frustrated. I'm using the debugger to my best ability but definitely need more experience with it.
/////////
I went back to pad and paper and kind of rewrote my code. Now I'm trying to store delimiters in an array and compare the elements of that array to the current string value. If they are equal, then we have come across a new word and we add it to the final string array. I'm struggling to figure out the placement and content of the "for" loop that I would use for this.
char * original = "USA,Canada,Mexico,Bermuda,Grenada,Belize";
//creating two intialized variables to count the number of characters and elements to add to the array (so we can allocate enough mmemory)
int stringCharCount = 0;
//by setting elementCount to 1, we can account for the last word that comes after the last comma
int elementCount = 1;
//calculate value of stringCharCount and elementCount to allocate enough memory for temporary word storage and for final array
for (int i = 0; i < 1000; i++) {
if (original[i] == '\0') {
break;
}
else {
stringCharCount++;
if (original[i] == ',') {
elementCount++;
}
}
}
//account for the final element
elementCount = elementCount;
char *tempWord = malloc(stringCharCount);
char *finalArray[elementCount];
int a = 0;
int b = 0;
//int c = 0;
//char *delimiters[4] = {".", ",", " ", "\0"};
for (int i = 0; i <= stringCharCount; i++) {
if (original[i] == ',' || original[i] == '\0') {
finalArray[a] = tempWord;
tempWord = malloc(stringCharCount);
tempWord[b] = '\0';
b = 0;
a++;
}
else {
tempWord[b++] = original[i];
}
}
for (int i = 0; i < elementCount; i++) {
printf("%s\n", finalArray[i]);
}
return 0;
}
Many issues. Suggest dividing code into small pieces and debug those first.
--
Un-initialize data.
// int stringCharCount;
int stringCharCount = 0;
...
stringCharCount++;
Or
int stringCharCount = strlen(givenString);
Other problems too: finalArray[] is never assigned a terminarting null character yet printf("%s\n", finalArray[i]); used.
Unclear use of char *
char *wordFiller = malloc(stringCharCount);
wordFiller = malloc(stringCharCount);
There are more bugs than lines in your code.
I'd suggest you start with something much simpler.
Work through a basic programming book with excercises.
Edit
Or, if this is about learning to program, try another, simpler programming language:
In C# your task looks rather simple:
string givenString = "USA,Canada Mexico,Bermuda.Grenada,Belize";
string [] words = string.Split(new char[] {' ', ',', '.'});
foreach(word in words)
Console.WriteLine(word);
As you see, there are much issues to worry about:
No memory management (alloc/free) this is handeled by the Garbage Collector
no pointers, so nothing can go wrong with them
powerful builtin string capabilities like Split()
foreach makes loops much simpler

find the minimum window in string S which will contain all the characters of string T

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
For example,
S = "ADOBECODEBANC"
T = "ABC"
Minimum window is "BANC".
void getstring(char str1[],char str2[],char hash[])
{
int len=strlen(str1);
int i=0,j; //i keeps the previous index
int min=INT_MAX;
int cnt=0;
for(j=0;j<len;j++)
{
if(hash[str1[j]]==-1) //means uninitialized, will be checked for first time only
{
cnt++;
hash[str1[j]]=j;
if(cnt==1)
i=j;
int y=check(hash,str2); //checking for the characters
//printf("y=%d",y);
if(y) //means all the characters are present
{
if( (j-i+1)<min)
{
min=j-i+1;
I=i;
J=j;
}
}
}
else if(hash[str1[j]]>=0)
{
hash[str1[j]]=j;
if(check(hash,str2) )
{
if( hash[str1[i]]==hash[str1[j]] ) //it means that we are moving the first
{ //index only
i=getmin(hash,str2); //get minimum index of the element
if( (j-i+1)<min)
{
min=j-i+1;
I=i;
J=j;
}
}
//else
}
else
{
if( hash[str1[i]]==hash[str1[j]] )
i=hash[str1[i]];
}
}//end of else-if
}//end of for
}
I have made the code for it using hash i.e. i am keeping the index values of the characters of the string T in the hash and using two indexes, as soon as i get any character ahead same as the character at the lower index, i first check the length and then updates the index.
This approach would take O(nk) in worst case.
n - is the number of characters in S
k - is the number of characters in T
Is there any approach which will take O(n) time for this problem?
So make a pass of S keeping track of when you last saw each letter in T.
At each point the farthest of the last seen letters will delimit the left edge of a window (with the current point being the right edge).
Of these windows, simply keep track of the smallest one seen so far. At the end of the algorithm this will be the smallest window overall.
Here is my java code which has passed all the test cases. I hope it might help you as well.
public class Solution {
public String minWindow(String s, String t) {
if(t.length()>s.length())
return "";
String result = "";
HashMap <Character, Integer> shouldFind = new HashMap<Character, Integer>();
HashMap <Character, Integer> hasFound = new HashMap<Character, Integer>();
int count =0, j=0, minWindow = s.length()+1, start=0, finish =0;
Integer sLength = s.length();
Integer tLength = t.length();
for(int i = 0 ; i < tLength ; i++)
{
char tChar = t.charAt(i);
if(!shouldFind.containsKey(tChar))
shouldFind.put(tChar,1);
else
shouldFind.put (tChar ,shouldFind.get(tChar)+1);
}
for (int i =0; i <sLength; i ++)
{
char sChar = s.charAt(i);
if(shouldFind.containsKey(sChar))
{
if(!hasFound.containsKey(sChar)){
hasFound.put(sChar, 1);
count++;
}
else {
if(hasFound.get(sChar) < shouldFind.get(sChar) )
count ++;
hasFound.put(sChar, hasFound.get(sChar) +1);
}
}
if(count == tLength)
{
char ch = s.charAt(j);
while (!hasFound.containsKey(ch) || hasFound.get(ch) > shouldFind.get(ch))
{
if(hasFound.containsKey(ch) && hasFound.get(ch)>shouldFind.get(ch))
hasFound.put(ch , hasFound.get(ch) -1);
j++;
ch = s.charAt(j);
}
//lets find the minimum window
if(minWindow > (i-j+1) )
{
minWindow = i - j + 1;
start = j;
finish = i+1;
result = s.substring(start, finish);
}
}}
return result;
}}

Resources