Upgrade to Pro — share decks privately, control downloads, hide ads and more …

師大資工系ACM-ICPC讀書會:壹、字串處理與大數運算

Cd57bf203d03722597a5c88007eb1c17?s=47 Maplewing
October 14, 2013

 師大資工系ACM-ICPC讀書會:壹、字串處理與大數運算

Cd57bf203d03722597a5c88007eb1c17?s=128

Maplewing

October 14, 2013
Tweet

Transcript

  1. 壹、字串處理與大數運算 師大資工系 灆洢 取自於<提升程式設計的邏輯思考力> 5.1 & 5.2

  2. 字串處理

  3. 使用string類別做為字串變數宣告的方法。 string s = “This is a string.”; 字串:使用C++ string類別

  4. string s = “This is a string.”; printf( “%c\n”, s[1]

    ); // => h s[2] = ‘a’; s[3] = ‘t’; printf( “%s\n”, s.c_str() ); // => That is a string. 字串取值:利用 [ ]
  5. string s = “This is a string.”; printf( “%c\n”, s[1]

    ); // => h s[2] = ‘a’; s[3] = ‘t’; printf( “%s\n”, s.c_str() ); // => That is a string. 字串轉C string:使用c_str()
  6. char cstr[] = “This is a string.”; string s =

    string(cstr); // s = “This is a string.” C string轉字串:利用string建構式
  7. string s; cin >> s; //以空白符、換行符、Tab做分隔切割 getline(cin, s); //以換行符做分隔切割 字串輸入:cin、getline

  8. string s = “This is a string.”; cout << s

    << ‘\n’; // => This is a string. printf( “%s\n”, s.c_str() ); // => This is a string. 字串輸出:cout、printf
  9. string s = “This is a string.”; cout << s.length()

    << ‘\n’; // => 17 字串長度:length() ( size() )
  10. string s = “This ”, t = “is ”; s

    += t; s += “a ”; s += “string.”; cout << s << ‘\n’; // => This is a string. 字串相接:+=、+
  11. string a = “This”, b = ”That”; a > b

    // true a < b // false a == b // false a != b // true a >= b // true a <= b // false 字串比對:>、<、==、!=、>=、<=
  12. 範例一:WRETYU (UVa 10082)

  13. 範例二:TeX Quotes (UVa 272)

  14. 範例三:Periodic Strings (UVa 455)

  15. •401 •10010 •10361 •537 •409 作業 •10878 •10815 •644 •10115

  16. 大數運算

  17. 大數是什麼?可以吃嗎? • 簡單來說,大數就是非常大的數字。 • C語言儲存整數的限制: int:-231≦ int ≦ 231-1 (21億,9~10位數)

    long long:-263 ≦ long long ≦ 263-1 (19位數) • 那要如何存一個100位數的數字呢? 利用大數!
  18. 如何儲存大數?(cont.) • 利用Array一格一格的特性,我們就可以把好幾位數分成好幾格。 • Ex. 儲存 1254 可以如下圖: 1 2

    5 4 array[0] array[1] array[2] array[3]
  19. 如何儲存大數?(cont.) • 但是int的Array沒辦法讓你直接儲存並分成一格一格。 • (X)你不可以這麼做:scanf( “%大數”, intArray ); • 所以我們利用可以讓我們一儲存就幫你分好一格一格的Array,也

    就是char的Array,把大數當成字串存進去。 • (O)你可以這麼做:scanf( “%s”, charArray );
  20. 如何儲存大數?(cont.) • 但是儲存完後,會有兩個問題: • 1. char陣列存完,數字會變成字元。若將存起來的 數字(已經是字元)做四則運算會先將其對應於ASCII 碼再進行加減。

  21. 如何儲存大數?(cont.) • 2.位數無法對齊 • Ex. 1254 + 916 Array1[0] Array1[1]

    Array1[2] Array1[3] Array1[4] Array1[5] 1 2 5 4 ‘\0’ Array2[0] Array2[1] Array2[2] Array2[3] Array2[4] Array2[5] 9 1 6 ‘\0’ 兩個個位數在不同格,難相加。
  22. 如何儲存大數?(cont.) • 解決方法:儲存時將位數倒過來儲存。 • Ex. 1254 + 916 Array1[0] Array1[1]

    Array1[2] Array1[3] Array1[4] Array1[5] 4 5 2 1 ‘\0’ Array2[0] Array2[1] Array2[2] Array2[3] Array2[4] Array2[5] 6 1 9 ‘\0’ 個位 十位 百位 千位 ……
  23. 如何儲存大數?(cont.) • 綜合以上解決方法,我們就可以依照以下步驟儲存大數! • 1.先利用char的Array將使用者輸入的大數分成一格一格。 • 2.將char的Array中一格一格的數字全部減去字元0的ASCII碼值存進int的 Array中,存進去時順便倒轉位置。 • 如此一來,大數就儲存進來了!(後面會有示範)

    • 題外話:利用char的Array中的’\0’可以找到此數字目前幾位數。
  24. 如何儲存大數?(cont.) CharArray[ 0] CharArray[ 1] CharArray[ 2] CharArray[ 3] CharArray[

    4] CharArray[ 5] ‘1’ (49) ‘2’ (50) ‘5’ (53) ‘4’ (52) ‘\0’ (0) IntArray[0] IntArray[1] IntArray[2] IntArray[3] IntArray[4] IntArray[5] 4 5 2 1  以存1254為例:
  25. 大數I/O • Input: • 利用scanf( “%s”, 字串名 ),再轉成int陣列。(倒過來放進去) • Output:

    • 利用for迴圈倒過來輸出。 • 1.紀錄位數,並從最高位數那格輸出到第0格。 • 2.將沒用到的格子補0,找到第一個不是0後開始輸出,直到第0格。(如果全部都是0 就輸出一個0)。 Array1[0] Array1[1] Array1[2] Array1[3] Array1[4] Array1[5] 4 5 2 1
  26. 大數加法(Ex. 1254+9160=10414 ) [0] [1] [2] [3] [4] Char Array

    Int Array Char Array Int Array + Result ‘1’ ‘2’ ‘5’ ‘4’ ‘\0’ -’0’ (-48)且倒轉 4 5 2 1 ‘9’ ‘1’ ‘6’ ‘0’ ‘\0’ -’0’ (-48)且倒轉 0 6 1 9 1. 位數對應相加 2.檢查進位 4+0=4 5+6=11 2+1=3 1+9=10 4 11 3 10 4 1 4 0 1
  27. 大數減法(Ex. 9160-1254=7906) [0] [1] [2] [3] [4] Char Array Int

    Array Char Array Int Array - Result ‘9’ ‘1’ ‘6’ ‘0’ ‘\0’ -’0’ (-48)且倒轉 0 6 1 9 ‘1’ ‘2’ ‘5’ ‘4’ ‘\0’ -’0’ (-48)且倒轉 4 5 2 1 1. 位數對應相減 2.檢查借位 0-4=-4 6-5=1 1-2=-1 9-1=8 -4 1 -1 8 6 0 9 7
  28. 大數乘法(Ex.19x19) • 首先,先來看一下乘法直式是如何做的! 1 9 1 9 1 7 1

    1 9 × + 3 6 1
  29. 大數乘法(Ex.19x19) • 把過程改變一下: 1 9 1 9 × + 1

    18 81 進位 361 1. 將A每一位數對B每一位數相 乘,並將結果加於A此位數 加B此位數的值。 2. 最後檢查進位。 Array[2] Array[1] Array[0] 第0格與第0格相乘,結果加於第0+0=0格 81 第1格與第0格相乘,結果加於第1+0=1格 9 9 1 第0格與第1格相乘,結果加於第0+1=1格 第1格與第1格相乘,結果加於第 1+1=2格
  30. 大數比較:>, < 和 == • 大於、小於:先比較位數,再從高次方開始比較。 • 等於:先比較位數,再比較每一位數是否相等。 Array1[0] Array1[1]

    Array1[2] Array1[3] Array1[4] Array1[5] 4 5 2 1 Array2[0] Array2[1] Array2[2] Array2[3] Array2[4] Array2[5] 9 1 6
  31. 大數除法&餘法(Ex.898653/52) • 以一格存4位數 [5] [4] [3] [2] [1] [0] 8

    9 8 6 5 3 5 2 8 9 3 7 1 3 7 8 7 1 4
  32. 大數延伸 • 大數開方 • 一格不只存1位數,也可存N位數,藉此可以儲存更大的大數: int:-231≦ int ≦ 231-1 (21億,9~10位數)

    long long:-263 ≦ long long ≦ 263-1 (19位數)
  33. 範例一:Primary Arithmetic (UVa 10035)

  34. 範例二:500! (UVa 623)

  35. •424 •10106 •465 •748 •10494 作業

  36. 謝謝聆聽 資料取自於<提升程式設計的邏輯思考力> 5.1 & 5.2