1. 程式人生 > 其它 >2021-2-4演算法基礎課一字串型別應用和高精度加法

2021-2-4演算法基礎課一字串型別應用和高精度加法

技術標籤:課堂筆記

字串

定義和使用

string s;
s = "abc";
cin >> s;
cout << s;

成員方法

方法名說明
size()s.size()返回字元s中字元的個數
find()s.find(子串, index)從字元s的index位置開始,查詢子串,如果找到返回子串開始的位置;否則返回-1。index預設為0
replace()s.replace(begin, len, 目標字串)將字串s從begin位置開始長度為len的子串換成目標字串

字串的遍歷

for(int i = 0; i < s.size(); i ++
) cout << s[i];

輸入一行字串

// Hello world!
string s;
getline(cin, s);

字串的應用

e2005 - 選擇你喜愛的水果

演算法思想

  • getline()輸入一行句子,直到沒有輸入為止
    • 遍歷每種水果
      • 如果該水果在句子中存在,那麼將水果替換為捲心菜
      • 否則,輸出不喜歡水果
#include <iostream>
#include <cstring>
using namespace std;

string f[] = {"apples", "bananas", "peaches"
, "cherries", "pears", "oranges", "strawberries"}; int main() { string s; while(getline(cin, s)) { int flag = -1; //遍歷水果 for(int i = 0; i < 7; i ++) { int index = s.find(f[i]); //從s中找到某個水果f[i] if
(index != -1) { flag = i; //用flag記錄找到的水果 break; } } if(flag == -1) cout << "You must not enjoy fruit." << endl; else { int index = s.find(f[flag]); //找到水果的開始位置 int len = f[flag].size(); //水果單詞的長度 s.replace(index, len, "Brussels sprouts"); cout << s << endl; } } return 0; }
#include <iostream>
#include <cstring>
using namespace std;

string f[] = {"apples", "bananas", "peaches", "cherries", "pears", "oranges", "strawberries"};

int main()
{
    string s;
    while(getline(cin, s))
    {
        string fruit = "";
        //遍歷水果
        for(int i = 0; i < 7; i ++)
        {
            int index = s.find(f[i]); //從s中找到某個水果f[i]
            if(index != -1)
            {
                fruit = f[i]; //用fruit記錄找到的水果
                break;
            }
        }
        if(fruit.size() == 0) cout << "You must not enjoy fruit." << endl;
        else
        {
            int index = s.find(fruit); //找到水果的開始位置
            int len = fruit.size(); //水果單詞的長度
            s.replace(index, len, "Brussels sprouts");
            cout << s << endl;
        }
    }
    return 0;
}

基礎演算法

演算法是解決問題的一般步驟。
我們要學習的基礎演算法:

  • 高精度數(大整數)數值處理
  • 排序演算法
  • 二分搜尋
  • 字首和和差分
  • 雙指標演算法
  • 位運算

高精度數值處理

  • 使用字串將大整數輸入進來
  • 把字串以數字的方式反向地儲存到陣列中,方便計算
  • 反向從高位向低位輸出就可以了

高精度加法

模擬列豎式做加法

  • 從低到高位,遍歷每一位
    • c[i] += a[i] + b[i];累加和,以及進位
    • 如果有進位的話,c[i + 1] = c[i] / 10;
    • 處理進位後的餘數,c[i] = c[i] % 10
#include <iostream>
using namespace std;
const int N = 6010; //常量
//a、b存加數,c存和
int a[N], b[N], c[N];
//la、lb表示加數的長度,lc表示和的長度
int la, lb, lc;

//將字串s中的大整數反向地儲存到a陣列,並返回位數
int read(string s, int a[])
{
    int len = s.size();
    for(int i = 1; i <= len; i ++)
        a[i] = s[len - i] - '0'; //將數字字元裝成數字
    return len;
}
//從高位到低位輸出大整數
void write(int a[], int la)
{
    //去掉前導0
    while(la > 1 && a[la] == 0) la --;
    for(int i = la; i >= 1; i --)
        cout << a[i];
}

int main()
{
    string s1, s2;
    cin >> s1 >> s2;
    
    la = read(s1, a);
    lb = read(s2, b);
    
    lc = max(la, lb); //和的位數
    //從高位到低位遍歷
    for(int i = 1; i <= lc; i ++)
    {
        c[i] += a[i] + b[i]; //累加和以及進位
        c[i + 1] = c[i] / 10; //處理進位
        c[i] = c[i] % 10; //處理進位後的餘數
    }
    //想更高一位進位
    if(c[lc + 1] != 0) lc ++; //位數增加1
    //輸出和
    write(c, lc);
    return 0;
}