Содержание сайта
Главная Новичку Цитаты Реализации Статьи Документация
Компании Программы Ссылки Обсуждение Обсуждение 2 Гостевая

Тестовая задача "Мама мыла раму"

Мой знакомый работает в крупной софтверной компании ISD. Основное направление: создание информационных систем для обслуживания больниц и медицинских лабораторий. Понятно, что больницы и лаборатории не наши. Пишут на Visual C++.

Я взял задачи с сайта компании http://www.isd.dp.ua/sample.html.ru и сделал их на Smalltalk-е.

Мама мыла раму

Написать функцию

	char* superSort (char*)
принимающую строку слов, разделенных пробелами. Каждое слово может состоять из латинских букв в нижнем регистре и цифр. Возвращаемым результатом должна быть строка из полученных слов, отсортированных в алфавитном порядке и разделенных пробелами, при этом во время сортировки при сравнении слов цифры должны игнорироваться, так, как будто бы их нет. Например, для входной строки
	ma79ma 9n8e7 mila r1a2m3u
результатом работы функции должно быть
	ma79ma mila 9n8e7 r1a2m3u

Решение: Разрезать строку по словам. Отсортировать слова без учета цифр в слове. Склеить отсортированную слова.

VisualWorks Smalltalk:

	words := 'ma79ma 9n8e7 mila r1a2m3u'
		runsFailing: [:each | each isSeparator].

	sortedWords := words asSortedCollection: 
		[:a :b |
		(a reject: [:each | each isDigit])
			<= (b reject: [:each | each isDigit])].

	sortedWords fold: [:a :b | a, ' ', b].

Dolphin Smalltalk:

	words := 'ma79ma 9n8e7 mila r1a2m3u' subStrings.

	sortedWords := words asSortedCollection: 
		[:a :b |
		(a reject: [:each | each isDigit])
			<= (b reject: [:each | each isDigit])].

	sortedWords inject: ''
		into: [:a :b |
			a = '' ifTrue: [ b ] ifFalse: [ a, ' ', b ] ].

Поэтапно (для VisualWorks):

  1. Разрезаем строку.

    	words := 'ma79ma 9n8e7 mila r1a2m3u' runsFailing: [:each | each isSeparator].
    

    Блок [:each | each isSeparator] выполняется для каждого символа в строке. И как только блок возвращает true кусочек строки копируется в коллекцию слов - words.

  2. Создать из строки "a" строку, в которой нет чисел.

    	a reject: [:each | each isDigit]
    

    Например

    'r1a2m3u' reject: [:each | each isDigit] вернет 'ramu'.

    #(1 -2 10 -20) reject: [:each | each > 0] вернет #(-2 -20).

    Работает это так - формируется новая коллекция с теми же элементами что и старая коллекция, за исключением тех элементов для которых выполняется условие в блоке, например each > 0.

  3. Отсортировать слова.

    	sortedWords := words asSortedCollection: 
    		[:a :b |
    		(a reject: [:each | each isDigit])
    			<= (b reject: [:each | each isDigit])].
    

    Условие сортировки указывается в блоке [:a :b | ... ]. Например для того чтобы отсортировать массив чисел в обратном порядке

    	#(5 1 4 2) asSortedCollection: [:a :b | a >= b]
    
    результат: отсортированная коллекция с элементами (5 4 2 1). В нашем случае при сортировке сравниваются строки у которых мы верезали числа
    	a reject: [:each | each isDigit]
    

  4. Склеить слова.

    	sortedWords fold: [:a :b | a, ' ', b]
    

    Как работает fold: лучше показать на примерах

    	#(1 2 3 4 5) fold: [:a :b | a + b]
    
    результат 15.
    	#('to' 'be' 'or' 'not' 'to' 'be') fold: [:a :b | a, ' ', b]
    
    результат 'to be or not to be'.

    Механика этого метода такова:
    Блок вычисляется для 1-го и 2-го элемента коллекции. Потом результат вычисления блока впрыскивается вместе с 3-м элементом коллекции в блок и т.д.
    Это легче понять изучив метод inject:into:.

Alex Baran




Есть комментарии? Пишите.