Array of strings with re - arrays

This answer suggested me a code for having an array of conditions for replacements. Now I want to have one more condition which cannot be coded in the same way.
kxyz
sxyz
pxyz
clxyz
bookabcd
lookabcd
cookabcd
packabcd
bank
lab
court
catch
This is the updated word list
import re
# List where first is pattern and second is replacement string
replacements = [("ing$", "xyz"), ("ed$", "abcd")]
with open("new_abcd.txt", "w") as new, open("abcd.txt") as original:
for word in original:
new_word = word
for pattern, replacement in replacements:
new_word = re.sub(pattern, replacement, word)
if new_word != word:
break
new.write(new_word)
Let's say I want to code a conditions for words like 'bank', 'lab', 'court', 'catch' that says add "x". One may wonder what is a pattern in these words. It's nothing but all of these words are consonant ending. I don't know the Python way of doing this, but I want something like if the word does not end in ("a" or "e" or "i" or "o" or "u") change it to something else. Can re handle this?

It is not hard to check with regex whether the word ends in a non-vowel, but in this case you would not replace but just if you have a match, add a letter to the word.
The regex which will check the non-existence of a vowel at the end of the given string is
[^aeiou]{1}$
Then in python I guess do something like
regexp = re.compile(r'[^aeiou]{1}$')
if regexp.search(word):
word += 'x'
# do more stuff
I would check thoroughly whether python built in ways to do this are not faster.

Related

Creating an array that only contains the letters from a string

So I'm trying to change the string \t\n into an array of all of word characters in the string. The array I want would look like this: ["t","n"].
So far I've tried:
input = " \t\n"
array = input.scan(/\w/)
I've tried this regular expression on this string on rubular and it matches with all of the word characters as I'd like it to.
However, when using input.scan(/\w) an empty array is returned.
Please forgive my ignorance as I'm still new to this, but why is this?
Here you go! You were really close.
input = " \t\n"
array = input.dump.scan(/\w/)
=> ["t", "n"]
The key is to use String#dump (see: https://ruby-doc.org/core-2.6.5/String.html#method-i-dump)
I am not familiar with ruby but you seem to be having string interpolation confusion.
Per https://www.ruby-forum.com/t/new-line-in-string/176797
input = " \t\n"
Gives you a string with a space, tab, and newline.
You probably want to use single quotes to literally get the string you wrote:
input = ' \t\n'
If you sorely want to stick with double-quotes then I believe this would work:
input = " \\t\\n"
You should read https://blog.appsignal.com/2016/12/21/ruby-magic-escaping-in-ruby.html to learn more about string interpolation in Ruby. I would link you to the official docs but my lack of ruby experience translates to a lack of official doc experience.
So like colleagues explain in comments, the letters which you have in "\t\n" string are not ordinary letters, only something called special characters so I am not sure but there is not easy way to take this characters from this string cause \t is like one character.
With normal string like tn you could do something like this
"tn".split("")
and that give you array which you want.
But on special characters like in the example. you could do something like this
a = "\t\n".split("")
a.map! do |e|
if e == "\t"
"t"
elsif e == "\n"
"n"
end
end
which give you, I believe, results which you want.

I need to print out all of the words in the file that begin with an uppercase character

i need to access a file and from that file i need to print out all the words that starts with a capital letter and also how many times the words have occurred. for example in the file there is a text "the Program should Display Files and also Files"
now the output should be:
Text
Program
Display
Files(2)//This word is written two times
enter image description here
while (!feof(..)) is normally not a good idea, instead write
while (fgets(readLine,sizeof(readLine), fpointer) != NULL)
{
}
it seems ptr is superfluous in this context, if you want to check for words in the line you should move it forward in the line?
alt. use instead the runtime function strtok:
for (ptr = strtok(readLine, " "); ptr != NULL; ptr = strtok(NULL, " ")
{
// now ptr will point to each word in the line, then you just check
// if the first character is upper case.
}
This sounds like a homework assignment, so I am not going to put the code here. I can give you the steps to take to have a general idea:
Open and read the file
Use something like strtok to split the lines into words
Loop over the words and check the first character (remember that a word is an array of chars. You can check if it's in range of 60 - 95 as based on the ascii table.
To count words you can create a hashmap in which you store the word with a count as value e.g. {word1: 1, word2: 2}
In the end you go over all the keys in the hashmap and print the key + count.

Read from array1 write from array2

Just learning some basic Ruby concepts as a beginner. Not really looking for code as such, rather some fundamental principles behind the following question (obviously feel free to express yourself with code if you need to :0)
In a simple redact text exercise, a user enters some text, then enters the word to be redacted, I'm fine with this and can make it work a number of ways.
However...
to deal with the possibility the user could enter upper and/or lower case letters for either the text or redacted word, I would need to create variables .downcase! again no problem there. But what if once the program runs, you want to return the words to their original state?
I thought perhaps you would need to create an array for the original text, where each word has an index within the array, create a corresponding array with the lowercase letters and if a word is NOT redacted, then you would compare the index from the lowercase array and write the corresponding index from the original array... does this sound correct or am I over thinking it, is there an easier way?
Thanks for your help
puts " What is your message"
text1 = gets.chomp
text2 = text1.downcase
puts "What is your secret word"
redact = gets.chomp.downcase!
words = text2.split (" ")
words.each do |x|
if
x == redact
print "REDACTED" + " "
else
print x + " "
end
end
I've added my working code, you can see that I've separated text1 the original from text2 which isn't strictly necessary as it stands, but to maintain the original formatting
Your solution sounds like it could work and as a beginner it may be useful to write a complete solution like that. But don't forget that ruby can do a lot of fun stuff for you.
Lets say we take input into sentence and the string to redact is stored in redact.
We can do something as simple as this:
sentence.gsub(/#{redact}/i, "*" * redact.length)
gsub finds all occurrences of the first argument and replaces it with the second, returning a new string.
First notice that we are using the redacted string as a regular expression for the first arg and the i indicates that it should match case insensitive, as you wanted.
Now the second arg is simply a string of asterisks of equivalent length to the redacted string.
For example if we have the following:
sentence = 'this is My Sentence'
redact = 'my'
puts sentence.gsub(/#{redact}/i, "*" * redact.length)
The above method will print this is ** Sentence.
Just one extra thing to note: this regex will match all occurrences of the string. For example, if redact = 'is', the resulting sentence will be th** ** My Sentence. You can re-write the regex to avoid this if that's not the expected use case.

How to check if two words are anagrams in c

I am trying to create a programme that is able to determine whether two inputted words are anagrams of each other.
The way in which I have been told to go by my tutor is to count how many of the first letter of one word there is, then compare to the other, then repeat for the rest of the letters. Therefore if the word gets to the end, then it considers them anagrams. However that is all he has helped me with, and I am really struggling with the problem.
The programme is required to print whether or not they are anagrams like so,
Success! "Carthorse" and "Orchestra" are anagrams!
Edit: Thanks guys for all of your responses, whilst I understand the whole idea behind them, I am finding it very difficult to put them into code, would anyone be able to simply writing the annotated code for me? It's not for a homework or anything, it's simply a personal project.
It sounds like you're new to C! Welcome :)
Tasks like that can seem complex, so the first step I'd do here is break it down into steps that you can google for how to do. So:
"count how many of the first letter of one word there is, then compare to the other, then repeat for the rest of the letter"
Read in the words/create variables of them
Create an array of length 26, to store each letter of the alphabet
Loop through the first word and for each letter, add one to the correct array index (a = 0, m = 12, etc)
e.g.
int index = string[i] - 'a'; // This will subtract the ascii value from the letter, getting a = 0 etc
letterCounts[index]++; // or letterCounts[index]--;
Loop through the second word, and for each letter, subtract one from the array index
If at the end any index is not 0, it is not an anagram.
Convert both strings to lowercase characters.
Create two arrays of 26 characters for the letters of the alphabet.
Run through each string counting the letters and incrementing the appropriate element in the alphabet arrays.
Then compare the two alphabet arrays and if they are equal for each character, your strings are anagrams.
1) Convert both strings to lowercase as necessary (use tolower from ctype.h).
2) Sort each string, e.g., by using qsort from stdlib.h:
static int cmp(const void *a, const void *b) { return *(char *)a - *(char *)b; }
qsort(str1, strlen(str1), 1, (cmp));
qsort(str2, strlen(str2), 1, (cmp));
3) Compare the sorted strings with strcmp from string.h - if equal, they are anagrams, otherwise not.

Searching for string that contains escaped characters

I have a binary file that has this particular string in it: ^#^Aname^#Team Fortress 2
This is how I tried to find it using memmem:
char *game = "Team Fortress 2";
sprintf(searchString,"\1\1name\1%s\0",game);
...
if(pos = memmem(buffer,result,searchString,strlen(searchString)))
How do I match the escaped characters ^# and ^A?
It seems to find \1\1name, but not with game in searchString.
Because your string contains nulls it isn't a valid C string and string manipulation functions such as memmem and strlen won't work. You'll have to roll your own version.
The simplest way is to loop through each index of the string, then use a second loop to check it against the string you're searching for. There are fancier and faster methods, but they are more difficult to understand and implement properly if you don't need the extra speed. See Wikipedia for an overview of the subject.
It isn't caret notation?
char *game = "Team Fortress 2";
sprintf(searchString,"%c%cname%c%s\0",(char)0, (char)1, (char)0, game);
...
if(pos = memmem(buffer,result,searchString,strlen(searchString)))

Resources