Design and implement a data structure for a compressed string iterator. The given compressed string will be in the form of each letter followed by a positive integer representing the number of this letter existing in the original uncompressed string.
Implement the StringIterator class:
next()
Returns the next character if the original string still has uncompressed characters, otherwise returns a white space.hasNext()
Returns true if there is any letter needs to be uncompressed in the original string, otherwise returns false
.Example 1:
Input [ "StringIterator ", "next ", "next ", "next ", "next ", "next ", "next ", "hasNext ", "next ", "hasNext "] [[ "L1e2t1C1o1d1e1 "], [], [], [], [], [], [], [], [], []] Output [null, "L ", "e ", "e ", "t ", "C ", "o ", true, "d ", true]
Explanation StringIterator stringIterator = new StringIterator( "L1e2t1C1o1d1e1 "); stringIterator.next(); // return "L " stringIterator.next(); // return "e " stringIterator.next(); // return "e " stringIterator.next(); // return "t " stringIterator.next(); // return "C " stringIterator.next(); // return "o " stringIterator.hasNext(); // return True stringIterator.next(); // return "d " stringIterator.hasNext(); // return True
Constraints:
1 <= compressedString.length <= 1000
compressedString
consists of lower-case an upper-case English letters and digits.compressedString
is in the range [1, 10^9]
100
calls will be made to next
and hasNext
.program main
use StringIterator_mod
implicit none
type(StringIterator) :: stringIterator
character(len=:), allocatable :: nextChar
logical :: hasNext
! Examples
call stringIterator%init("L1e2t1C1o1d1e1")
do while (stringIterator%hasNext())
nextChar = stringIterator%next()
write (*, "(A)", advance="no") trim(nextChar)
end do
write (*, *)
call stringIterator%init("")
do while (stringIterator%hasNext())
nextChar = stringIterator%next()
write (*, "(A)", advance="no") trim(nextChar)
end do
write (*, *)
contains
subroutine init(this, compressedString)
class(StringIterator), intent(inout) :: this
character(len=*), intent(in) :: compressedString
this%compressedString = compressedString
this%index = 1
end subroutine init
function next(this) result(res)
class(StringIterator), intent(inout) :: this
character(len=1), allocatable :: res
if (this%index > len(this%compressedString)) then
res = ' '
else
read (this%compressedString(this%index:), fmt='(A)', iostat=ioStatus) res
this%index = this%index + len(res) + 1
end if
end function next
function hasNext(this) result(res)
class(StringIterator), intent(inout) :: this
logical :: res
res = this%index <= len(this%compressedString)
end function hasNext
end program main
module StringIterator_mod
implicit none
private
public :: StringIterator
type :: StringIterator
character(len=:), allocatable :: compressedString
integer :: index
contains
procedure :: init => init
procedure :: next => next
procedure :: hasNext => hasNext
end type StringIterator
contains
subroutine init(this, compressedString)
class(StringIterator), intent(inout) :: this
character(len=*), intent(in) :: compressedString
this%compressedString = compressedString
this%index = 1
end subroutine init
function next(this) result(res)
class(StringIterator), intent(inout) :: this
character(len=1), allocatable :: res
if (this%index > len(this%compressedString)) then
res = ' '
else
read (this%compressedString(this%index:), fmt='(A)', iostat=ioStatus) res
this%index = this%index + len(res) + 1
end if
end function next
function hasNext(this) result(res)
class(StringIterator), intent(inout) :: this
logical :: res
res = this%index <= len(this%compressedString)
end function hasNext
end module StringIterator_mod
temp.f95:2:9: 2 | use StringIterator_mod | 1 Fatal Error: Cannot open module file āstringiterator_mod.modā for reading at (1): No such file or directory compilation terminated.
! Declare the data structure for the compressed string iterator
type StringIterator
! Private variables
integer :: index = 1
character(len=1) :: current_char = ' '
character(len=1) :: next_char = ' '
integer :: count = 0
logical :: has_next = .false.
! Private methods
contains
! Advance the iterator to the next character
subroutine advance()
integer :: i
! If the current character is not a space, increment the count
if (current_char /= ' ') then
count = count + 1
end if
! If the count is greater than 0, decrement the count
if (count > 0) then
count = count - 1
end if
! If the count is 0, advance to the next character
if (count == 0) then
index = index + 1
if (index <= len(compressed_string)) then
current_char = compressed_string(index:index)
count = 1
else
current_char = ' '
end if
end if
end subroutine advance
! Check if there are any more characters to be uncompressed
function has_next() result(has_next)
logical :: has_next
! If the current character is not a space, or the count is greater than 0,
! then there are still characters to be uncompressed
if (current_char /= ' ' .or. count > 0) then
has_next = .true.
else
has_next = .false.
end if
end function has_next
! Return the next character
function next() result(next_char)
character(len=1) :: next_char
! If there are still characters to be uncompressed, advance the iterator
if (has_next()) then
call advance()
end if
! Return the next character
next_char = current_char
end function next
end type StringIterator
! Declare the main program
program main
! Declare the variables
type(StringIterator) :: string_iterator
character(len=1) :: next_char
logical :: has_next
! Create a new string iterator
string_iterator = StringIterator(compressed_string="L1e2t1C1o1d1e1 ")
! Loop until there are no more characters to be uncompressed
do while (string_iterator%has_next())
! Get the next character
next_char = string_iterator%next()
! Print the next character
write (*,*) next_char
end do
end program main
! Declare the compressed string
character(len=1), parameter :: compressed_string = "L1e2t1C1o1d1e1 "
! Declare the main entry point
entry main
! Call the main program
call main
! End of file
end
temp.f95:13:9: 13 | subroutine advance() | 1 Error: Unclassifiable statement at (1) temp.f95:14:24: 14 | integer :: i | 1 Error: Components in TYPE at (1) must precede CONTAINS temp.f95:17:41: 17 | if (current_char /= ' ') then | 1 Error: Unexpected block IF statement at (1) temp.f95:18:33: 18 | count = count + 1 | 1 Error: Unexpected assignment statement at (1) temp.f95:19:15: 19 | end if | 1 Error: Expecting END TYPE statement at (1) temp.f95:22:31: 22 | if (count > 0) then | 1 Error: Unexpected block IF statement at (1) temp.f95:23:33: 23 | count = count - 1 | 1 Error: Unexpected assignment statement at (1) temp.f95:24:15: 24 | end if | 1 Error: Expecting END TYPE statement at (1) temp.f95:27:32: 27 | if (count == 0) then | 1 Error: Unexpected block IF statement at (1) temp.f95:28:33: 28 | index = index + 1 | 1 Error: Unexpected assignment statement at (1) temp.f95:29:57: 29 | if (index <= len(compressed_string)) then | 1 Error: Unexpected block IF statement at (1) temp.f95:30:59: 30 | current_char = compressed_string(index:index) | 1 Error: Syntax error in argument list at (1) temp.f95:31:29: 31 | count = 1 | 1 Error: Unexpected assignment statement at (1) temp.f95:32:20: 32 | else | 1 Error: Unexpected ELSE statement at (1) temp.f95:33:38: 33 | current_char = ' ' | 1 Error: Unexpected assignment statement at (1) temp.f95:34:19: 34 | end if | 1 Error: Expecting END TYPE statement at (1) temp.f95:35:15: 35 | end if | 1 Error: Expecting END TYPE statement at (1) temp.f95:36:11: 36 | end subroutine advance | 1 Error: Expecting END TYPE statement at (1) temp.f95:40:31: 40 | logical :: has_next | 1 Error: Components in TYPE at (1) must precede CONTAINS temp.f95:44:56: 44 | if (current_char /= ' ' .or. count > 0) then | 1 Error: Unexpected block IF statement at (1) temp.f95:45:33: 45 | has_next = .true. | 1 Error: Unexpected assignment statement at (1) temp.f95:46:16: 46 | else | 1 Error: Unexpected ELSE statement at (1) temp.f95:47:34: 47 | has_next = .false. | 1 Error: Unexpected assignment statement at (1) temp.f95:48:15: 48 | end if | 1 Error: Expecting END TYPE statement at (1) temp.f95:49:11: 49 | end function has_next | 1 Error: Expecting END TYPE statement at (1) temp.f95:53:41: 53 | character(len=1) :: next_char | 1 Error: Components in TYPE at (1) must precede CONTAINS temp.f95:56:32: 56 | if (has_next()) then | 1 Error: Unexpected block IF statement at (1) temp.f95:57:30: 57 | call advance() | 1 Error: Unexpected CALL statement at (1) temp.f95:58:15: 58 | end if | 1 Error: Expecting END TYPE statement at (1) temp.f95:61:36: 61 | next_char = current_char | 1 Error: Unexpected assignment statement at (1) temp.f95:62:11: 62 | end function next | 1 Error: Expecting END TYPE statement at (1) temp.f95:66:12: 66 | program main | 1 Error: Unexpected PROGRAM statement at (1) temp.f95:68:43: 68 | type(StringIterator) :: string_iterator | 1 Error: Unexpected data declaration statement at (1) temp.f95:69:33: 69 | character(len=1) :: next_char | 1 Error: Unexpected data declaration statement at (1) temp.f95:70:23: 70 | logical :: has_next | 1 Error: Unexpected data declaration statement at (1) temp.f95:76:31: 76 | do while (string_iterator%has_next()) | 1 Error: Symbol āstring_iteratorā at (1) has no IMPLICIT type temp.f95:78:37: 78 | next_char = string_iterator%next() | 1 Error: Symbol āstring_iteratorā at (1) has no IMPLICIT type temp.f95:82:7: 82 | end do | 1 Error: Expecting END PROGRAM statement at (1) temp.f95:83:16: 83 | end program main | 1 Error: Expected label āstringiteratorā for END PROGRAM statement at (1) temp.f95:86:68: 86 | character(len=1), parameter :: compressed_string = "L1e2t1C1o1d1e1 " | 1 Error: Unexpected data declaration statement at (1) temp.f95:89:10: 89 | entry main | 1 Error: ENTRY statement at (1) cannot appear within a PROGRAM temp.f95:73:23: 73 | string_iterator = StringIterator(compressed_string="L1e2t1C1o1d1e1 ") | 1 Error: ācompressed_stringā at (1) is not a member of the āstringiteratorā structure
class StringIterator:
def __init__(self, compressedString: str):
self.s = compressedString
self.i = 0
self.count = 0
self.ch = " "
def next(self) -> str:
if not self.hasNext():
return " "
if self.count == 0:
self.ch = self.s[self.i]
self.i += 1
while self.i < len(self.s) and self.s[self.i].isdigit():
self.count = self.count * 10 + int(self.s[self.i])
self.i += 1
self.count -= 1
return self.ch
def hasNext(self) -> bool:
return self.i < len(self.s) or self.count != 0
The main idea of the algorithm is to iterate through the compressed string, extracting each character and its associated count of repetitions. Each extracted character is stored in 'ch' and its count of repetitions is stored in 'count'. The 'next()' function checks if there are still letters to uncompress - if there aren't, it returns a white space. The 'next()' function also checks if the current count of repetitions for the character 'ch' is 0 - if it is, it extracts the next character from the compressed string until it encounters a digit, then extracts the whole count value. The 'hasNext()' function checks if there are any more characters in the compressed string or if the count of repetitions is not 0, meaning there are still characters to be uncompressed.
#include <string>
class StringIterator {
public:
StringIterator(const std::string& compressedString) {
s = compressedString;
i = 0;
count = 0;
ch = ' ';
}
char next() {
if(!hasNext()) return ' ';
if(count == 0) {
ch = s[i++];
while(i < s.size() && isdigit(s[i])) {
count = count * 10 + (s[i++] - '0');
}
}
count--;
return ch;
}
bool hasNext() {
return i < s.size() || count != 0;
}
private:
std::string s;
int i;
int count;
char ch;
};
The main idea of the algorithm is to iterate through the compressed string, extracting each character and its associated count of repetitions. Each extracted character is stored in 'ch' and its count of repetitions is stored in 'count'. The 'next()' function checks if there are still letters to uncompress - if there aren't, it returns a white space. The 'next()' function also checks if the current count of repetitions for the character 'ch' is 0 - if it is, it extracts the next character from the compressed string until it encounters a digit, then extracts the whole count value. The 'hasNext()' function checks if there are any more characters in the compressed string or if the count of repetitions is not 0, meaning there are still characters to be uncompressed.