I am starting to write a MIPS program where I get a String in hexadecimal representation say A23B , and want to put it together into 1 Entire hex number. I am really lost in the part as how to extract say one Digit , say B and convert it into hex for mips then fetch the other one. I am not looking for an entire program as I know this is not what it is for but as something to start with as I am really lost, thank you.
Consider this. Say your data segment looks like this
.data
str: .space 5 #enough room for a 4 digit hex number
And further, that the memory pointed to by str contains the string you want to convert to a number. To get its first byte into $t1, you would use:
la $t0 str
lb $t1 0($t0)
Next, there are four cases:
'0' < $t1 < '9'
'a' < $t1 < 'f'
'A' < $t1 < 'F'
Error
I'll assume you know how to check these cases.
In all but the last case, we must increment sum by the given value; therefore the next step for the cases would be:
sum += $t1 - '0'
sum += $t1 - 'a' + 10
sum += $t1 - 'A' + 10
Obviously this is pseudo-code, but it illustrates the main point that the ASCII values for the digits and letters are sequential, so calculating their value is trivial.
Lastly, because we know that each digit represents exactly 4 bits, and because we begin reading from left to right, we must shift the sum left by 4 bits:
sll $sum $sum 4
That is the steps for one character, to convert an entire string you would need to loop over each character.
Related
This is a question I encountered in a Test and I am not able to solve it. Every time I think of an algorithm, a new corner case comes that fails it. Can someone please explain me, how to move through the problem ?
Problem Statement
The Cytes Lottery is the biggest lottery in the world. On each ticket, there is a string of a-z letters. The company produces a draw string S. A person wins if his/her ticket string is a special substring of the draw string. A special substring is a substring which can be formed by ignoring at most K characters from drawString. For example, if draw string = "xyzabc" and tickets are [ac zb yhja] with K=1 then the winning tickets will be 2 i.e ac (won by ignoring "b" in drawstring) and zb (won by ignoring "a" in drawstring).
Now some people change their ticket strings in order to win the lottery. To avoid any kind of suspicion, they can make the following changes in their strings.
They can change character 'o' to character 'a' and vice versa
They can change character 't' to character 'l' and vice versa
They can erase a character from anywhere in the string
Note that they can ignore at most 'K' characters from the draw string to get a match with the ticket string.
Write an algorithm to find the number of people who win the lottery (either honestly or by cheating).
Input:
The first line of the input consists of an integer - numTickets, representing the number of tickets (N).
The second line consists of a string - drawString, representing the draw string (S).
The third line consists of N space-seperated strings - tickets1, tickets2,........., ticketsN representing the tickets.
The last line consists of an integer-tolerance, representing the maximum number of characters that can be deleted from the drawString(K).
Output:
An integer representing the number of winning tickets (either fairly or by cheating).
Constraints:
0 <= numTickets <= 1000
0 <= length of drawString <= 200
0 <= length of tickets[i] <= 200
0 <= tolerance <= 1000
Note:
The drawString contains lowercase English alphabets
Example:
Input:
3
aabacd
abcde aoc actld
1
Output:
2
Recently while taking some algorithm practise at leetcode i came across a solution, i understood everything except the part where the user converts an element in a string to an integer, look at the code below. Hopefully someone can explain this to me. Thanks for replies in advnace.
a := 234
b := strconv.Itoa(a)
c := int(b[0]-48) // why do we subtract 48?
48 is the code of the '0' character in the ASCII table.
Go stores strings as their UTF-8 byte sequences in memory, which maps characters of the ASCII table one-to-one to their code.
The digits in the ASCII table are listed contiguously, '0' being 48. So if you have a digit in a string, and you subtract 48 from the character's code, you get the digit as a numeric value.
Indexing a string indexes its bytes, and in your case b[0] is the first byte of the b string, which is 2. And '2' - 48 is 2.
For example:
fmt.Println('0' - 48)
fmt.Println('1' - 48)
fmt.Println('2' - 48)
fmt.Println('3' - 48)
fmt.Println('4' - 48)
This outputs (try it on the Go Playground):
0
1
2
3
4
“b” is a string “234”, a string is a slice of rune therefore b[0] is a byte/rune, in this case a value of 50 which is the decimal value of a “2” in ascii. So “c” will be 50-48=2
Question:
Is it save to get substring n characters from a text in RPG using MOVEL function which take a text with length x and store it to a variable with capacity n?
Or the only save way to get the first n character is using SUBST?
The background of the question is one of my colleague getting the first 3 characters from a database with 30 char in length is using MOVEL to a variable with length only 3 char (like truncating the rest of it). The strange way, sometimes the receive variable is showing minus character ('-'), sometimes doesn't. So I assume using MOVEL is not a safe way. I am thinking like string in C which always terminated by '\0', you need to use strcpy function to get the copy save, not assigning using = operator.
Anybody who knows RPG familiar with this issue?
MOVEL should work. RPG allows several character data types. Generally speaking, someone using MOVEL will not be dealing with null terminated strings because MOVEL is an old technique and null terminated strings are a newer data type. You can read up on the MOVEx operations and the string operations in the RPG manual. To get a better answer, please post your code, including the definitions of the variables involved.
EDIT: Example of how MOVEL handles signs.
dcl-s long char(20) inz('CORPORATION');
dcl-s short char(3) inz('COR');
dcl-s numb packed(3: 0);
// 369
c movel long numb
dsply numb;
// -369
c movel short numb
dsply numb;
*inlr = *on;
With signed numeric fields in RPG the sign is held in the zone of the last byte of the field. So 123 is X'F1F2F3' but -123 is X'F1F2D3'. If you look at those fields as character strings they will have 123 and 12L in them.
In your program you are transferring something like "123 AAAAAL" to a 3 digit numeric field so you get X'F1F2F3' but because the final character is X'D3' that changes the result to have a zone of D i.e. X'F1F2D3'
You anomaly is dependent on what the 30th character contains. If it is } or any capital letter J to R then you get a negative result. [It doesn't matter whether the first 3 characters are numbers or letters because it is only the second half of the byte, the digit, that matters in your example.]
The IBM manuals say:
If factor 2 is character and the result field is numeric, a minus zone is moved into the rightmost position of the result field if the zone from the rightmost position of factor 2 is a hexadecimal D (minus zone). However, if the zone from the rightmost position of factor 2 is not a hexadecimal D, a positive zone is moved into the rightmost position of the result field. Other result field positions contain only numeric characters.
Don
In Fortran, what would be the practical way to read:
A 1. 2. 3.
if the first character is an "A", but to not read the:
Z
rest if the first character is a "Z" for example.
If I try to read the line at whole:
read(1,*)char, number1, number2, number3
then an error will occur if the numbers are missing. So I need a way to read an "A" stay on that line, and depending on the "A" or a "Z" read, if needed the rest.
Here is a good trick you may not know. You can put a character variable in place where the unit number is in the read statement. You would be reading from the variable instead of the file.
Start by declaring a character variable long enough to read the longest line. Read the whole line into this variable. From the variable, read that first character. If it is an A, read in the numbers. It would look like this:
character*130 :: MyLine
read(1,'(a130)') MyLine
read(MyLine,*) char
if (char == 'A') then
read(MyLine,*) char, number1, number2, number3
endif
You can always read the flag and use an expression in the iolist to determine whether you want to read any more stuff.
az.f90:
program az
implicit none
real number1, number2, number3
character azflag
integer iunit
integer i
open(newunit=iunit,file='az.txt',status='old')
do
number1 = -1
number2 = -1
number3 = -1
read(iunit,*,end=10) azflag, (number1,number2,number3 &
,i=1,merge(1,0,any(azflag==['A','a'])))
if(any(azflag==['A','a'])) then
write(*,*) 'numbers read!'
else
write(*,*) 'nothing read'
end if
write(*,*) number1, number2, number3
end do
10 continue
end program az
az.txt:
A 1. 2. 3.
Z
a 4. 5. 6.
z
Output:
numbers read!
1.000000 2.000000 3.000000
nothing read
-1.000000 -1.000000 -1.000000
numbers read!
4.000000 5.000000 6.000000
nothing read
-1.000000 -1.000000 -1.000000
A slight deviation from what you want would be to replace the first letter by the number of numbers to read, like
3 1. 2. 3.
0
2 3.14 -1.
Then if the maximum number of elements you want to read in each row is nmax then declare
integer::i,n
real(dimension=nmax)::number
and use
read(1,*) n, (number(i), i=1,n)
If you really want to keep using letters, you can hack something using iachar() to get the ASCII value of the character converted into the number of reals to read.
If I am given a string of letters 'abcd' and I want to convert this to a vector of numbers V = [1,2,3,4] which corresponds to the position of letters in the alphabet table, how can I do this?
Just subtract 'a'. Add one to map 'a' to 1. The subtraction sends the results into a double.
V = C - 'a' + 1;
For example,
C = 'helloworld';
C - 'a' + 1
ans =
8 5 12 12 15 23 15 18 12 4
To map 'a' to 1, 'b' to 2, etc., use the DOUBLE function to recast the character back to its ASCII code number, then shift the value:
V = double(charString)-96;
EDIT: Actually, you don't even need the call to DOUBLE. Characters will automatically be converted into double-precision numbers when you perform any arithmetic with another double-precision number (the default type for MATLAB variables). So, the following is an even simpler answer:
V = charString-96;
use uint8, then subtract the char value of 'a', then push that onto a vector. link