2010年1月29日 星期五

2010/01/29 文數字排序

由"in.txt"讀取一串的文字或數字,將其按數字、大寫英文字母、小寫英文字母排序。

出自  程式設計隊訓練教材  NO.9 文數字排序

輸入範例:
DoYouHave1456879DollarsToBorrow
輸出範例:
1456789BDDHTYaaelloooooorrrsuvw

25 則留言:

  1. Dim str(100) As String
    Private Sub Form_Load()
    Open App.Path & "/in.txt" For Input As #1
    Input #1, x
    Close #1
    For i = 1 To Len(x)
    str(i) = Mid(x, i, 1)
    Next i
    For i = 1 To Len(x)
    For j = 1 To Len(x)
    If str(i) < str(j) Then change str(i), str(j)
    Next j
    Next i
    Open App.Path & "/out.txt" For Output As #2
    For i = 1 To Len(x)
    Print #2, str(i);
    Next i
    Close #2
    End Sub

    Public Sub change(a, b)
    c = a
    a = b
    b = c
    End Sub

    回覆刪除
  2. 做完程式突然想到如果加入符號會怎麼樣...
    於是
    輸入:DoYouHave1456879DollarsToBorrow/*-+.\=-)(*&^%$#@!~`}{":?><;'[]|_

    輸出:!"#$%&'()**+--./1456789:;<=>?@BDDHTY[\]^_`aaelloooooorrrsuvw{|}~

    如果題目中出現進階的符號排序
    則有可能以怎樣的形式增加難度出題呢?
    而且在記事本中"輸出範例"內容遇到"]"
    會出現自動斷行
    而在部落格的發言上則是在";"出現自動斷行
    這有什麼意義嗎?

    回覆刪除
  3. 假如樸用陣列有辦法做嗎@@
    有的話是否請老師示範一下~~
    Dim a(999) As String
    Private Sub Form_Load()
    Open App.Path & "\in.txt" For Input As #1
    Input #1, n
    Close #1

    xx = Len(n)

    For i = 1 To xx
    a(i) = Mid(n, i, 1)
    Next i

    For i = 1 To xx - 1
    For j = i To xx
    If a(i) > a(j) Then
    change a(i), a(j)
    End If
    Next j
    Next i

    Open App.Path & "\out.txt" For Output As #2
    For i = 1 To xx
    ans = ans & a(i)
    Next i
    Print #2, ans
    Close #2

    End Sub
    Public Sub change(x, y)
    z = x
    x = y
    y = z
    End Sub

    回覆刪除
  4. 高仔、阿瑋好,
    1.還是覺得題目的輸出和說的不一樣,不是說數字、小寫、大寫嗎?可是輸出的是數字、大寫、小寫。
    2.如果不管1說的事,你們的程式是OK的,先拆成陣列,再做個基本的排序,沒什麼痛苦的。
    3.高仔說的符號並沒什特殊,只是在找一些內定的設定而已,像是如何印出少數特殊的符號之類的設定而已,不容易出現在考題中。
    4.哈,阿瑋好,我喜歡會出題目的人。
    先是能解決題目,然後還要進階成為可以出題目的人。
    「時代考驗青年」「青年創造時代」以前的偉人這麼說過的。
    5.回歸阿瑋的問題,如果不用陣列,我會用一個結果字串
    dim ans as string
    asn=""
    然後一樣將輸入的字串,一次拆一個字出來,然後,
    「插入」適當的位置。
    6.插入排序,也是排序方法中的一種,值得練習哦。
    小小說明一下,
    例如:
    字串ans已經有13個字長了,而且是照著「升冪」的方式的字串。
    新的字a出現,發現比第7個字大,比第8個字小,那麼
    ans = mid(ans,1,7) & a & mid(ans,8)
    新的ans就出現了。
    細節交給你們了。

    哦,我想,這麼多題,只是這麼大家你寫一次,我寫一次,還是需要大家在一起的時候,一題一題說一說吧。
    試試看,先將返校日那天的時間給空出來,花個兩個小時來說說吧。
    先這樣子,大家繼續努力哦。

    回覆刪除
  5. Private Sub Form_Load()
    Dim x As String
    Open App.Path & "\in.txt" For Input As #1
    Input #1, x
    Close #1
    For i = 1 To Len(x) - 1
    For j = i To Len(x)
    q = Mid(x, i, 1)
    w = Mid(x, j, 1)
    If q > w Then
    temp = Mid(x, i, 1)
    Mid(x, i, 1) = Mid(x, j, 1)
    Mid(x, j, 1) = temp
    End If
    Next j
    Next i
    Open App.Path & "\out.txt" For Output As #1
    Print #1, x
    Close #1
    End Sub

    回覆刪除
  6. 老師我問一下@@
    事先把讀入的資料直接轉成String 應該就不用 在1個1個字放進陣列了吧??

    回覆刪除
  7. 阿揚好,
    怪了,這個程式的輸出會正確嗎?
    Mid(x, i, 1) = Mid(x, j, 1)
    這行指令會正確嗎?
    ??????

    回覆刪除
  8. 執行前
    DoYouHave1456879DollarsToBorrow
    執行後
    1456789BDDHTYaaelloooooorrrsuvw
    可以ㄚ@@

    回覆刪除
  9. temp = Mid(x, i, 1)
    Mid(x, i, 1) = Mid(x, j, 1)
    Mid(x, j, 1) = temp

    這個就是阿偉 高仔 用的CHANGE 阿 只是 我沒用直接打這樣

    回覆刪除
  10. Y揚好,
    好吧,等我回到台灣後再試試吧,人家說成敗論英雄。
    我認為錯的原因是:
    a(i)=a(j)
    這是陣列的元素,前面的陣列元素當成是變數來存值,後面的陣列元素提供值。

    mid(x,i,1)=mid(x,j,1)
    的前方,是由函數mid傳回來的一個值,應該(?)不能成為一個變數來存值的。
    就像
    a=3
    b=5
    a=b
    這樣子是可以的。
    但是
    3=5
    這樣的式子,得到的只是false
    而不是想要的結果。
    ????

    回覆刪除
  11. 真的耶=ˋ= PRUNT mid(x,i,1)=mid(x,j,1)
    是FALSE
    我用新增監看視看 他真的依照我打的換過去了=O=

    等返校日那天 再來好好研究@@

    回覆刪除
  12. 老師這樣說 我想到上面阿偉 和高仔的程式

    change 3,5

    Public Sub change(x, y)
    z = x
    x = y 那這個X=Y 不就是 3=5嗎??
    y = z
    End Sub

    回覆刪除
  13. Y揚好,
    好了,我找到了。
    真是難為渡假滑雪中的熊掌啊。
    1.你的程式,真的可以執行,答案正確。
    2.你說的別人的程式的部分,要回頭說到「傳數值呼叫」「傳位址呼叫」,這部分計概也會考哦。
    change a(i),a(j)
    sub change(x,y)
    副程式那邊並沒有特別說明,於是,就成了「傳位址呼叫」,a(i)和x,是完全相等的位址,改變x就會改變a(i)。
    但是,如果呼叫方是
    change 3,5
    因為沒有「位址」可以傳過去,所以就成了「傳數值呼叫」,x,y有數值3,5但是,這邊怎麼改變,也不會影響原來的地方。(總不能3以後都成了5吧?)
    3.回到原來的「謎」。
    mid這個函數傳回的值是個「字串」,而vb中的字串變數的存法,我猜可能是像c語言中的pointer指標的方式,(這個一來是猜,二來太深了,不懂沒關係的),於是明明只是個傳回值的「字串」卻也可以成為變數。所以,你的「錯誤」程式,卻有了「正確」的結果。再強調一次,是「錯誤的程式」。
    4.「謎」的進一步。
    你們在前面的幾個程式中,很喜歡將數字也拿來「字串」處理,很多時候也「剛好」會得到「正確」的答案,但是,在這兒就有不同了。
    x="123"
    t = mid(x,1,1)
    mid(x,1,1)=mid(x,3,1)
    mid(x,3,1)=t
    這個程式,可以執行。x 會成為 "321"
    但是,
    x=123
    t = mid(x,1,1)
    mid(x,1,1)=mid(x,3,1)
    mid(x,3,1)=t
    這個程式執行就會出現錯誤了。
    哦,找得很辛苦說。
    所以,錯誤的程式,還是不要學。利用別人「奇怪」的錯誤,而「怪怪」地成為「正確」的方式,緊急時,或是,走頭無路時,可以用用,但是,現在是學習的過程,不要用。
    先學「正確」的程式,「正確」的方法。(別人的錯誤,不歸我管)

    回覆刪除
  14. 說一個陳年往事,
    for i = 10 to 20
    c = c+1
    next i
    ? c
    for j = 1 to 2 step 0.1
    d = d+1
    next j
    ? d
    上面這個程式片斷,照理說,c,d都是11吧。
    你去試試吧。

    回覆刪除
  15. 嗯嗯@@

    老師辛苦辣@@

    謝謝老師 ~~

    回覆刪除
  16. 那個
    for j = 1 to 2 step 0.1
    d = d+1
    next j
    ? d

    1.9 到2時 突然 D 停止動作了...

    回覆刪除
  17. 結果好像是誤差的關係喔@@

    當循環到第10次的時候,i變成1.9000001,第11次時i變成2.0000001 了!!!
    2.0000001>2,所以最後一次循環沒被執行

    回覆刪除
  18. Dim aa(100) As String
    Private Sub Form_Load()
    Open App.Path & "/in.txt" For Input As #1
    Input #1, X
    MaxStr = Len(X)
    For i = 1 To MaxStr
    aa(i) = Mid(X, i, 1)
    Next i
    For i = 1 To MaxStr
    For j = 1 To MaxStr
    If aa(i) < aa(j) Then change aa(i), aa(j)
    Next j
    Next i
    Close #1
    Open App.Path & "/out.txt" For Output As #2
    For i = 1 To MaxStr
    Print #2, aa(i);
    Next i
    Close #2
    End Sub

    Public Sub change(a, b)
    c = a
    a = b
    b = c
    End Sub

    回覆刪除
  19. 小白好,
    程式OK,
    For i = 1 To MaxStr
    For j = 1 To MaxStr
    這兩行,以後要改一改。

    回覆刪除
  20. Dim a(1000) As String
    Public Sub Form_Load()
    Me.Hide
    Open App.Path & "/in.txt" For Input As #1
    Open App.Path & "/out.txt" For Output As #2
    Line Input #1, sep
    For i = 1 To Len(sep)
    a(i) = Mid(sep, i, 1)
    Next i
    For i = 1 To Len(sep)
    For j = i + 1 To Len(sep)
    If a(j) < a(i) Then bb = a(i): a(i) = a(j): a(j) = bb
    Next j
    Next i
    For i = 1 To Len(sep)
    Print #2, a(i);
    Next i
    Close #1
    Close #2
    End
    End Sub
    3分41秒

    回覆刪除
  21. 回頭再寫一次,真的容易多了,是不是啊,阿揚。
    加油。
    熊掌

    回覆刪除
  22. Private Sub Form_Load()
    Dim k(100)
    Dim l(100)
    Open App.Path & "\in.txt" For Input As #1
    Input #1, x
    m = Len(x)
    For i = 1 To m
    k(i) = Mid(x, i, 1)
    Next
    For i = 1 To m - 1
    For j = 1 To m - 1
    If k(j) > k(j + 1) Then Call change(k(j), k(j + 1))
    Next j
    Next i
    For i = 1 To m - 1
    For j = 1 To m - 1
    If k(j) >= "A" And k(j) <= "Z" Then
    l(j) = k(j)
    k(j) = ""
    End If
    Next j
    Next i
    For i = 1 To m
    Print k(i);
    Next
    For i = 1 To m
    Print l(i);
    Next
    Close
    End Sub

    Sub change(a, b)
    t = a
    a = b
    b = t
    End Sub

    回覆刪除
  23. -.- 空白全都不見了 老師請見諒Orz

    回覆刪除
  24. #試用Python重寫一次
    f=open('in.txt','r')
    x=f.read()
    print(x)

    #將字串變成list,再來排序
    y=list(x)
    print(y)

    y.sort()
    print(y)

    f.close()

    f=open('out.txt','w')
    for i in y:
    f.write(i)
    f.close()

    #熊掌 2020/5/19

    回覆刪除