2015-10-29 3 views
1

Я очень новичок в SML и имею некоторый фон в C/C++. Я пытаюсь написать функцию с именем reverseString, которая получает строку для изменения. Довольно просто. Используя вспомогательную функцию, я смог написать функцию, которая меняет любую заданную строку с добавлением дополнительного символа к результату. Например:Идеи для обратных строк в SML

- reverseString("hello"); 
val it = "ollehh" : string 

Любая помощь в том, как преодолеть это препятствие будет чрезвычайно полезна. Пожалуйста, имейте в виду, что я пытаюсь реализовать функцию без каких-либо дополнительных функций (то есть функции, которые не были использованы в моей сломанной реализации):

fun reverseAux(s:string, i:int) : string = 
    if i = 0 then str(String.sub(s, 0)) 
    else str(String.sub(s, i-1))^reverseAux(s, i-1); 

fun reverseString(s:string) : string = 
    reverseAux(s, size(s)); 
+0

Простейшая модификация для достижения функциональности, которую вы ищете, заключается в изменении 'i = 0' на' i = 1' или путем изменения 'size (s)' to 'size (s) -1' –

+0

' String.sub (s, 0) 'встречается дважды в результате, хотя один из времен он замаскирован под« String.sub (s, i-1) », когда« i »равен 1. – molbdnilo

+0

Спасибо, Кевин и Мольбнило. Это то, что я искал. Использование рекурсии для изменения строки привело меня в замешательство ... –

ответ

1

В дополнение к моему комментарию, это Простейшее решение, когда вы знаете о поиске по шаблону:

fun helper [] = [] 
| helper [x] = [x] 
| helper (l::ls) = (helper ls) @ [l]; 

fun reverse s = implode (helper (explode s)); 

explode и implode являются функциями, которые соответственно преобразующие string в char list и наоборот. Список легче перемещаться, чем строка.

3

Вы можете просто взрываются, затем foldl, а затем Implode:

fun reverse s = implode (foldl op:: [] (explode s)); 
5

Принятая ответ (который заслуживает того, чтобы быть принятым) объясняет, как вы могли бы сделать это с нуля - что это отличная идея, когда вы начинаете, но она включает в себя @, что является довольно дорогостоящей операцией (см. this для отличного обсуждения того, как, казалось бы, линейные алгоритмы могут быть квадратичными под капотом). Есть способ избежать этого, хотя объяснение это немного связано (Google «хвост рекурсивный обратный», если вы заинтересованы). Вместо этого встроенная функция rev уже реализует эффективную отмену списка. С ее помощью, а также с помощью встроенного в состав оператора o может позволить reverseString быть создан в одной строке:

val reverseString = implode o rev o explode; 

Обратите внимание, что я использовал val вместо fun. Композиция представляет собой функцию более высокого порядка, которая возвращает другие функции, и я принимаю , используя композицию, чтобы непосредственно создать функцию, которую я хочу, а не определять ее с нуля. Способность упаковывать много в одну строку кода является одним из главных преимуществ функционального программирования. В этом случае он использует эту композицию оператора цепочки и читается справа налево. Он говорит, что, чтобы обратить вспять строку, вы должны сначала взорвать ее в список, а затем отменить лифт, а затем взорвать его обратно в строку.

 Смежные вопросы

  • Нет связанных вопросов^_^