"Explanation why ABAP has four unique characters and not three as expected:
"the second A is a cyrillic character which looks equal to "normal A" but has different unicode value
PARAMETERS p_text type string DEFAULT `ABАP is excellent ` LOWER CASE.
"class (S)AP (C)ommunity (C)oding (C)hallenge (S)eries
CLASS scccs DEFINITION.
PUBLIC SECTION.
METHODS solve
IMPORTING
text TYPE string
RETURNING
VALUE(result) TYPE string_table.
ENDCLASS.
CLASS test DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
PUBLIC SECTION.
PRIVATE SECTION.
DATA cut TYPE REF TO scccs.
METHODS setup.
METHODS abap_is_excellent FOR TESTING.
METHODS lorem_ipsum_dolor_sit_amet FOR TESTING.
METHODS many_trailing_spaces FOR TESTING.
METHODS many_leading_spaces FOR TESTING.
METHODS many_space_in_the_middle FOR TESTING.
METHODS complex FOR TESTING.
ENDCLASS.
CLASS scccs IMPLEMENTATION.
METHOD solve.
result = REDUCE string_table( "STRING_TABLE is the output...
LET
"clean the text from spaces
text_wo_double_spaces = replace( regex = '(\s)(?=\1)' val = text with = `` occ = 0 )
"delete trailing and leading blanks
cleaned_text = shift_left( val = shift_right( val = text_wo_double_spaces ) )
"number of words is the number of blanks + 1
num_words = count_any_of( val = cleaned_text sub = ` ` ) + 1 IN
INIT
"fill first result line with "number of words"
lines = VALUE #( ( |Number of words: { num_words }| ) )
" derive words via SEGMENT of cleaned string
FOR word
IN REDUCE string_table(
INIT w = VALUE #( )
"do read the words and store in table (equals SPLIT INTO TABLE)
FOR i = 1 THEN i + 1 UNTIL i > num_words
NEXT w = VALUE #( BASE w ( segment( val = cleaned_text index = i ) ) ) )
NEXT lines = VALUE #(
"transfer word-string to result table (BASE for keeping existing lines)
BASE lines ( |Number of unique characters in the word: { word } - {
"now calculate number of distinct characters in each word
lines( REDUCE string_table(
"prepare the character table
INIT chars = VALUE string_table( )
"do aas many times as the word has characters; pos is the offset for current character
FOR pos = 0 THEN pos + 1 WHILE pos < strlen( word )
NEXT chars = COND #(
"if current character does not exist in character table,...
WHEN NOT line_exists( chars[ table_line = word+pos(1) ] )
"...then insert current character
THEN VALUE #( BASE chars ( word+pos(1) ) )
" otherwise keep current character table as it is
ELSE chars ) ) ) }| ) ) ) .
ENDMETHOD.
ENDCLASS.
CLASS test IMPLEMENTATION.
METHOD setup.
cut = NEW #( ).
ENDMETHOD.
METHOD abap_is_excellent.
cl_abap_unit_assert=>assert_equals(
act = cut->solve( `ABАP is excellent ` )
exp = VALUE string_table(
( `Number of words: 3` )
( `Number of unique characters in the word: ABАP - 4` )
( `Number of unique characters in the word: is - 2` )
( `Number of unique characters in the word: excellent - 6` ) ) ).
ENDMETHOD.
METHOD lorem_ipsum_dolor_sit_amet .
cl_abap_unit_assert=>assert_equals(
act = cut->solve( `Lorem ipsum dolor sit amet` )
exp = VALUE string_table(
( `Number of words: 5` )
( `Number of unique characters in the word: Lorem - 5` )
( `Number of unique characters in the word: ipsum - 5` )
( `Number of unique characters in the word: dolor - 4` )
( `Number of unique characters in the word: sit - 3` )
( `Number of unique characters in the word: amet - 4` )
) ).
ENDMETHOD.
METHOD many_trailing_spaces.
cl_abap_unit_assert=>assert_equals(
act = cut->solve( `start ` )
exp = VALUE string_table(
( `Number of words: 1` )
( `Number of unique characters in the word: start - 4` )
) ).
ENDMETHOD.
METHOD many_leading_spaces.
cl_abap_unit_assert=>assert_equals(
act = cut->solve( ` end` )
exp = VALUE string_table(
( `Number of words: 1` )
( `Number of unique characters in the word: end - 3` )
) ).
ENDMETHOD.
METHOD many_space_in_the_middle.
cl_abap_unit_assert=>assert_equals(
act = cut->solve( `start end` )
exp = VALUE string_table(
( `Number of words: 2` )
( `Number of unique characters in the word: start - 4` )
( `Number of unique characters in the word: end - 3` )
) ).
ENDMETHOD.
METHOD complex.
cl_abap_unit_assert=>assert_equals(
act = cut->solve( ` one two thréé ÄÖÜ ••• ` )
exp = VALUE string_table(
( `Number of words: 5` )
( `Number of unique characters in the word: one - 3` )
( `Number of unique characters in the word: two - 3` )
( `Number of unique characters in the word: thréé - 4` )
( `Number of unique characters in the word: ÄÖÜ - 3` )
( `Number of unique characters in the word: ••• - 1` )
) ).
ENDMETHOD.
ENDCLASS.
START-OF-SELECTION.
cl_demo_output=>display_data( NEW scccs( )->solve( p_text ) ).
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
5 | |
4 | |
3 | |
3 | |
2 | |
2 | |
2 | |
1 | |
1 | |
1 |