为什么这段代码只排序一次?它应该去递归吗? 我尝试复制和使用函数几次但结果相同
import Data.Char(digitToInt)
main = do
let input = "014191633811200332532482200388402372212502263534033843815342500002960238365203448225037732492472423604003650332739521403775274133234120141613263263284258349238980000299142823491385101303491002740220381422901923619346834530150013398923221429717193717"
print $ bubblesort input
bubblesort input
| input == sorted = sorted
| otherwise = bubblesort sorted
where
sorted = sort_once input
sort_once::String->String
sort_once [] = []
sort_once (x:[]) = x:[]
sort_once (x:y:[]) = sort_two x y
sort_once input@(x:y:xy) = (sort_two x y)++(sort_once xy)
--sort_two::String=>Char->Char
sort_two aa bb |
a<b = aa:bb:[]::String |
otherwise = bb:aa:[]::String
where
a=digitToInt aa::Int
b=digitToInt bb::Int
如果有兴趣我使用下面的提示修改代码,感谢大家的答案:
import Data.Char(digitToInt)
main = do
let input = "014191633811200332532482200388402372212502263534033843815342500002960238365203448225037732492472423604003650332739521403775274133234120141613263263284258349238980000299142823491385101303491002740220381422901923619346834530150013398923221429717193717"
let result = bubblesort (string_to_int_arr input) ::[Int]
print result
bubblesort::[Int]->[Int]
bubblesort input
| (input == sorted) = sorted
| otherwise = bubblesort sorted
where
sorted = sort_once input
string_to_int_arr :: String->[Int]
string_to_int_arr input = map (read . (:"")) input :: [Int]
sort_once::[Int]->[Int]
sort_once [] = []
sort_once (x:[]) = x:[]
sort_once (x:y:[]) = (lesser x y):(greater x y):[]
sort_once (x:y:xy) = (lesser x y):(sort_once $ (greater x y):xy)
greater::Int->Int->Int
greater a b
| a>b=a
| otherwise=b
lesser::Int->Int->Int
lesser a b
| a<b=a
| otherwise=b
答案 0 :(得分:3)
sort_once
未实现bubblesort迭代。记住bubblesort的整体想法:你想“一直冒出最大的元素”。
但是,假设你在开始时拥有最大的元素,之后有一些任意元素,比如"321"
。 sort_once
会发生什么?
sort_once "321" = sort_two '3' '2' ++ sort_once "1"
= sort_two '3' '2' ++ "1"
= ['2', '3'] ++ sort_once "1"
= "231"
如果sort_once
应该反映完整的bubblesort迭代,则这是不正确的。毕竟,最大的元素现在停留在第二个位置而不是最后一个位置。 sort_once
的下一次使用不会改变:
sort_once "231" = sort_two '2' '3' ++ sort_once "1"
= sort_two '2' '3' ++ "1"
= ['2', '3'] ++ sort_once "1"
= "231"
因此,您的“排序”会在一次迭代后停止。你可能会问,如何解决这个问题。好吧,在sort_once
的递归调用中,您需要考虑更大的元素:
sort_once (x:y:xy) =
let [lesser, greater] = sort_two x y
in lesser : (sort_once (greater : xy))
-- ^^^^^^^
-- still look at the greater element
顺便说一下,这应该鼓励您将sort_two
的类型更改为Char -> Char -> (Char, Char)
。毕竟,sort_two
返回的列表应该总是有两个元素。
Int
来比较两个字符。但是,您可以将字符与<
和>
进行比较。尝试在没有sort_two
的情况下实施digitToInt
。<
中使用了>
或sort_two
,概括了sort_once
和sort
,以便您可以对[Int]
进行排序, [Integer]
,或任何其他可以比较的东西。提示:查看(<)
。