I have the following c++ method:
typedef unsigned long p3tOffsetType;
p3tOffsetType buildString(std::string string)
{
for (stringMap::const_iterator string_iterator = strings.begin(); string_iterator != strings.end(); ++string_iterator)
{
if (string_iterator->second == string)
return string_iterator->first;
}
p3tOffsetType new_string_offset = string_offset;
strings[string_offset] = string;
string_offset += string.size() + 1;
return new_string_offset;
}
What does the function do? I can give more of the code if needed.
The code is a snippet from a P3T file packer found in the source P3TBuilder (version 2.7).
I need to know this because I am trying to
Assuming that strings is a map<p3tOffsetType, std::string> and that string_offset is initialized to zero, it seems to do the following: Imagine that you call the method a few times with, say, "Hello", "Hi", and "Hey", and that you would treat all these strings as C-strings and store them in the same char array. The array elements would then be {'H', 'e', 'l', 'l', 'o', '\0', 'H', 'i', '\0', 'H', 'e', 'y', '\0'}. The starting indices of the three strings are 0, 6, and 9, respectively. What the method does is to create a map that maps these starting indices to the strings, so strings[0] == "Hello", strings[6] == "Hi", and strings[9] == "Hey". Also, it eliminates duplicates, so calling the method again with "Hello" would leave the map unchanged.
It iterates over strings which is a map from p3tOffsetType to string. If the sought after string is found in the map then it returns the offset. If not then it stores the string with the current offset as key and adds the length of the string to the global variable string_offset (which I assume initialized to zero).
Basically, a map of strings and their offsets is built. So if you called it with "Hello", "test" and "bla" it would contain the following:
strings[0] = "Hello"
strings[6] = "test"
strings[11] = "bla"
This keeps track of the strings and where they are located in the "bigger" string, so to speak.
Related
If my string is-
''Felix Underhalm'' and I want to turn into...
list = ['F', 'E', 'L', 'I', 'X']
How should I do it?
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 1 year ago.
Improve this question
Need to translate text to Morse for an assignment.
The outputted format of the Morse needs to be like this ".../---/... "space" .../---/..."
With a space in between words , and a / in between characters. However the / cannot be at the beginning or end of word.
Mine outputs like this " .../---/.../ "space" /.../---/.../ " Obviously failing.
I am sure there is a simple fix but I seem to be having a meltdown, Please help.
// Morse alphabet array
String morse [28] = {
".-",
"-...",
"-.-.",
"-..",
".",
"..-.",
"--.",
"....",
"..",
".---",
"-.-",
".-..",
"--",
"-.",
"---",
".--.",
"--.-",
".-.",
"...",
"-",
"..-",
"...-",
".--",
"-..-",
"-.--",
"--..",
" "
};
// Alphabet array
char letters [27] = {
'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',
' '
};
// Translates a text char to a morse char
String char2Morse (char a) {
int b = tolower (a);
for (int index = 0; index < 28; index ++) {
if ( b == (letters [index])) {
return (morse [index]);
}
}
}
// Translates a text string into Morse
String word2Morse (String wordy) {
String returnstring = "";
for (int i = 0; i < wordy.length (); i ++) {
returnstring += (char2Morse (wordy[i]));
returnstring += ('/');
}
return returnstring ;
}
The key here is to understand when exactly you would need to add a / after the character. Currently, inside the for loop of word2Morse, you are adding / after translating every character.
However, you actually don't want / before or after an word. However, you can't tell the program to not put a slash before or after an word, because it doesn't know what is a word. Instead you need to find a simpler logic.
Imagine you are trying to translate the word: hello world
You are doing fine translating the first 5 character. However, without any changes to your code, you will add a slash right after the first o, which is not what you want.
But why don't you want a slash after o? Because it is the end of a word. And how do you know that? It's because the next character is a space.
Now, that's a logic you can explain: You don't want a slash if the next character is a space!
So go back to your for loop:
for (int i = 0; i < wordy.length (); i ++) {
returnstring += (char2Morse (wordy[i]));
returnstring += ('/');
}
You can add that logic before you add / to your string:
for (int i = 0; i < wordy.length (); i ++) {
returnstring += (char2Morse (wordy[i]));
if (wordy[i+1] != ' ') {
returnstring += ('/');
}
}
Now, you will never add a slash if there's a space after your current character.
However, you will have similar problem after the space, and before the letter w. But once again, you can form a similar logic here: You don't want a slash if your current character is a space!
This time I will not write the code out, because it should be your homework. But the essence would be to add more boolean test in that if statement.
However, there is one more thing to watchout, which is when you are approaching the end of the sentence. Once you have translated the last character d, it would once again try to check if the next character is a space. However, you do not have another character afterwards. And trying to check it will end in errors. So in that if statement, you also want to check you are not at the last character!
One other thing to note is that you probably don't want to write out something like:
char letters [27] = {
'a',
'b',
'c',
'd',
⋮
⋮
It's way too repetitive, don't you think? Instead, say if myChar is 'g' , you can get a number by doing myChar - 'a', which would give you 6.
So for most of the char2Morse, you can do it like:
String char2Morse(char a) {
char lower_a = tolower (a);
return morse[lower_a - 'a'];
}
The only thing to catch here is that you can't do it with the space character, which can be tested out with a if-statement:
String char2Morse(char a) {
if (a == ' ') {
return morse[27];
}
else {
return morse[tolower(a) - 'a'];
}
}
I have two lists of different lengths and i want match the items based on their actual relation. One list is the secondary structure elements and other list is aligned sequence. I want to match the secondary structure to its residues in the other list. And adjust the length of secondary structure by inserting '-' to that of gaps in the aligned sequence. The items in ss corresponds to RRCAVVTG in seq.
ss=['-', '-', 'E', 'E', 'E', 'E', 'S', 'S']
seq≈["---------------RRCAVVTG"]
for m in seq:
found=[i for i in list(m)]
sscount=0
sscount1=0
for char,ssi in zip(found,ss):
if char!='-' :
print char , sscount, ssi
sscount+=1
else:
print char, sscount1, '#'
sscount1+=1
The expected results:
---------------##EEEESS
---------------RRCAVVTG
But i get the following results:
- 0 #
- 1 #
- 2 #
- 3 #
- 4 #
- 5 #
- 6 #
- 7 #
I hope I understood the question right. First we fill the string ss with - and then compare it to the string inside seq using zip():
ss = ['-', '-', 'E', 'E', 'E', 'E', 'S', 'S']
seq = ["---------------RRCAVVTG"]
out = ''
for ch1, ch2 in zip('{:->{}}'.format(''.join(ss), len(seq[0])), seq[0]):
if ch1=='-' and ch2 !='-':
out += '#'
elif ch1=='-' and ch2 == '-':
out += '-'
else:
out += ch1
print(out)
print(seq[0])
Prints:
---------------##EEEESS
---------------RRCAVVTG
for m in seq:
found=[i for i in list(m)]
sscount=0
sscount1=0
num=0
for char,ssi in zip(found,itertools.cycle(ss)):
if char!='-' :
print char , sscount, ss[num]
d.append(ss[num])
num+=1
sscount+=1
else:
print char, sscount1, '#'
sscount1+=1
I need to convert a given string of numbers to the word those numbers correspond to. For example:
>>>number_to_word ('222 2 333 33')
'CAFE'
The numbers work like they do on a cell phone, you hit once on the second button and you get an 'A', you hit twice and you get an 'B', etc. Let's say I want the letter 'E', I'd have to press the third button twice.
I would like to have some help trying to understand the easiest way to do this function. I have thought on creating a dictionary with the key being the letter and the value being the number, like this:
dic={'A':'2', 'B':'22', 'C':'222', 'D':'3', 'E':'33',etc...}
And then using a 'for' cycle to read all the numbers the in the string, but I do not know how to start.
You need to reverse your dictionary:
def number_to_word(number):
dic = {'2': 'A', '22': 'B', '222': 'C', '3': 'D', '33': 'E', '333': 'F'}
return ''.join(dic[n] for n in number.split())
>>> number_to_word('222 2 333 33')
'CAFE'
Let's start inside out. number.split() splits the text with your number at white space characters:
>>> number = '222 2 333 33'
>>> number.split()
['222', '2', '333', '33']
We use a generator expression ((dic[n] for n in number.split())) to find the letter for each number. Here is a list comprehension that does nearly the same but also shows the result as a list:
>>> [dic[n] for n in number.split()]
['C', 'A', 'F', 'E']
This lets n run through all elements in the list with the numbers and uses n as the key in the dictionary dic to get the corresponding letter.
Finally, we use the method join() with an empty string as spectator to turn the list into a string:
>>> ''.join([dic[n] for n in number.split()])
'CAFE'
I'm trying to write a pig latin translator in F#. To translate, I need to know if a word starts with a vowel or not. To do that, I'm trying to use this function which I wrote...
(*Tests if an element is in a list*)
let isInList elementToFind listToCheck =
List.fold(fun a b -> a || b = elementToFind) false listToCheck;
to test if the first character in a word is in a list of all vowels. Here is what my attempt looks like
(*Takes a word and translates it to pig latin*)
let translateWord wordToTranslate : string =
let startsWithVowel = isInList(wordToTranslate.[0], ['A', 'E', 'I', 'O', 'U', 'a', 'e', 'i', 'o', 'u']);
if startsWithVowel then
translateWordStartingWithVowel(wordToTranslate)
else
translateWordStartingWithConsenant(wordToTranslate);
Which is giving several errors. It's saying wordToTranslate.[0] doesn't have enough type constrants and startsWithVowel is of the wrong type. The full error texts are
Severity Code Description Project File Line
Error The operator 'expr.[idx]' has been used on an object of indeterminate type based on information prior to this program point. Consider adding further type constraints Pig Latin FSharp
Severity Code Description Project File Line
Error This expression was expected to have type
bool
but here has type
('a * (char * char * char * char * char * char * char * char * char * char) list) list -> bool Pig Latin FSharp
How can I fix this approach so that it does what I want it to do? I'm relatively new to F# so any help would be greatly appreciated!
You need parenthesis in the type annotation, otherwise it applies to the return value, not parameter:
let translateWord (wordToTranslate : string) = ...
You do not need parenthesis and commas when passing arguments to isInList function. To separate elements of a list use ; instead of , (, is used to separate elements of a tuple).
let startsWithVowel = isInList wordToTranslate.[0] ['A'; 'E'; 'I'; 'O'; 'U'; 'a'; 'e'; 'i'; 'o'; 'u']
That will fix the compilation errors.
By the way, the following is cleaner, faster and will give you the same results:
let startsWithVowel = Seq.contains wordToTranslate.[0] "AEIOUaeiou"