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.
Related
How many inversions are there in a binary string of length n ?
For example , n = 3
000->0
001->0
010->1
011->0
100->2
101->1
110->2
111->0
So total inversions are 6
The question looks like a homework, that's why let me omit the details. You can:
Solve the problem as a recurrency (see Толя's answer)
Make up and solve the characteristic equation, get the solution as a close formula with some arbitrary constants (c1, c2, ..., cn); as the matter of fact you'll get just one unknown constant.
Put some known solutions (e.g. f(1) = 0, f(3) = 6) into the formula and find out all the unknown coefficients
The final answer you should get is
f(n) = n*(n-1)*2**(n-3)
where ** means raising into power (2**(n-3) is 2 in n-3 power). In case you don't want to deal with recurrency and the like stuff, you can just prove the formula by induction.
It is easy recurrent function.
Assume that we know answer for n-1.
And after ato all previous sequences we add 0 or 1 as first character.
if we adding 0 as first character that mean that count of inversions will not be changed: hence answer will be same as for n-1.
if we adding 1 as first character that mean count of inversions will be same as before and will be added extra inversion equals to count of 0 into all previous sequences.
Count of zeros ans ones in sequences of length n-1 will be:
(n-1)*2^(n-1)
Half of them is zeros it will give following result
(n-1)*2^(n-2)
It means that we have following formula:
f(1) = 0
f(n) = 2*f(n-1) + (n-1)*2^(n-2)
I want to read some values from a file called Input.txt. The input file looks like this:
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
....
in total its 36 lines of 1,2,3 and 4s
then I use the following code to read from the file:
program outputtest
implicit none
double precision, allocatable, dimension(:) :: A,B,C,D
integer :: counter,ii, ierror
ierror=0
counter=1
open(39, action='read', name='input.txt', status='old')
do
read(39,100, IOSTAT=Ierror)
100 Format(T8,I1)
If (Ierror>0) then
print *, 'error when reading'
stop
end if
If (ierror<0) then
print*, 'end of file reached'
exit
end if
counter=counter+1
end do
If (.not.allocated(A)) ALLocate(A(counter))
If (.not.allocated(b)) ALLocate(b(counter))
If (.not.allocated(c)) ALLocate(c(counter))
If (.not.allocated(d)) ALLocate(d(counter))
do ii=1, counter-1
read(39,110, IOSTAT=ierror) A(ii), B(ii), C(ii), D(ii)
110 Format(T8, I4, T16, I4, T24, I4, T32, I4)
If (ierror.neqv.0) exit
end do
close(39)
write (*,120) A
write (*,120) B
write (*,120) C
write (*,120) D
120 Format('result:', 1x,I2)
end program outputtest
The problem is now that the A,B,C,D are all equal to zero, i.e. my output is:
result: 0
result: 0
result: 0
....
This means that I do not read either from the correct lines or I make another mistake. I used in vim the option ruler to see what lines those entries are in and used those lines together with T. I created the file Input.txt by using tabs. What is my mistake?
A two things:
You don't do a rewind in your file. At first you read through the whole file to get the number of lines, but without a rewind, you start reading at the end -- which means nothing gets actually read into the arrays.
read with explicit formats is dangerous. You have to be really certain that the input file matches the format precisely. In your case, I'd to as #high-performance-mark suggested and use fmt=*. Your input file should easily be read automatically.
That's what I can gleam from a quick browse. See if that helps.
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.
I've been reading the Wikipedia article about the Knuth-Morris-Pratt algorithm and I'm confused about how the values are found in the jump/partial match table.
i | 0 1 2 3 4 5 6
W[i] | A B C D A B D
T[i] | -1 0 0 0 0 1 2
If someone can more clearly explain the shortcut rule because the sentence
"let us say that we discovered a proper suffix which is a proper prefix and ending at W[2] with length 2 (the maximum possible)"
is confusing. If the proper suffix ends at W[2] wouldn't it be size of 3?
Also I'm wondering why T[4] isn't 1 when there is a prefix and suffix of size 1: The A.
Thanks for any help that can be offered.
Notice that the failure function T[i] does not use i as an index, but rather as a length. Therefore, T[2] represents the length of the longest proper border (a string that is both a prefix and suffix) of the string formed from the first two characters of W, rather than the longest proper border formed by the string ending at character 2. This is why the maximum possible value of T[2] is 2 rather than 3 - the substring formed from the first two characters of W can't have length any greater than 2.
Using this interpretation, it's also easier to see why T[4] is 0 rather than 1. The substring of W formed from the first four characters of W is ABCD, which has no proper prefix that is also a proper suffix.
Hope this helps!
"let us say that we discovered a proper suffix which is a proper prefix and ending at W[2] with length 2 (the maximum possible)"
Okay, the length can be maximum 2, it's correct, here is why...
One fact: "proper" prefix can't be the whole string , same goes for "proper" suffix(like proper subset)
Lets, W[0]=A W[1]=A W[2]=A , i.e the pattern is "AAA", so, the (max length)proper prefix can be "AA" (left to right) and, the (max length) proper suffix can be "AA" (right to left)
//yes, the prefix and suffix have overlaps (the middle "A")
So, the value would be 2 rather than 3, it would have been 3 only if the prefix was not proper.
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