【C++】文字列の最初と最後の文字を返す s.front(), s.back()

beta.atcoder.jp

  • こういうしりとりでしか使わないかもしれないけれど。
#include<valarray>
#include<iostream>

using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define pn(s) cout << (#s) << " " << (s) << endl

int main(){
    string s = "abcde";
    
    cout << s.front() << endl;
    cout << s.back() << endl;

    return 0;
}
a
e

【C++】いもす法を覚えた!abc017_3

問題

beta.atcoder.jp

  • この問題ではナイーブに解くとO(N * M)
  • いもす法を使うとO(N + M)

いもす法の覚えかた

  • いもす法で検索して本人の解説を読む
    • 喫茶店の例までで十分
  • 今回の問題の解答を読む
  • サンプル1のテストデータで図を書き、いもす法のシミュレートまで行う

f:id:peroon:20181209185910j:plain

印象

  • 後の計算に使うための統計情報を効率よく求める方法

その他の学び

  • int[], vectorなどは0で初期化されていない
  • したいならこう書く
const int N_MAX = 100000;
int table[N_MAX+10] = {};

私の提出

beta.atcoder.jp

【C++】数値計算用だけどあまり知られていないvalarrayを使ってみた。内積、循環シフトなど

#include<valarray>
#include<iostream>

using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define pn(s) cout << (#s) << " " << (s) << endl

void printValArray(valarray<int> A){
    for(int a : A){
        cout << a << " ";
    }
    cout << endl;
}

int main(){
    valarray<int> A = {1,2,3};
    valarray<int> B = {10,20,30};
    
    // 和
    auto C = A + B;
    printValArray(C);

    // 積
    auto D = A * B;
    printValArray(D);

    // 合計
    int sum = A.sum();
    pn(sum);

    // max
    int max = A.max();
    pn(max);

    // サイズ
    int size = A.size();
    pn(size);

    // 内積
    int inner_product = (A * B).sum();
    pn(inner_product);

    // 循環シフト
    valarray<int> E = {1,2,3,4,5};
    printValArray(E.cshift(1));
    printValArray(E.cshift(-1));

    return 0;
}
$ g++ -std=c++11 experiment.cpp && ./a.out

11 22 33
10 40 90
sum 6
max 3
size 3
inner_product 140
2 3 4 5 1
5 1 2 3 4

valarrayを知ったきっかけ

beta.atcoder.jp

C++ foreach的な書き方で書き換えるときは参照渡しを

#include<stdio.h>
#include<iostream>

using namespace std;
#define FOR(i,a,b) for(int i=(a);i<(b);++i)

void printArray(int *A, int n){
    FOR(i, 0, n){
        cout << A[i] << " ";
    }
    cout << endl;
}

int main(){
    int A[] = {1,2,3};
    printArray(A, 3);

    for(int v : A){
        v = 0;
    }
    printArray(A, 3);

    for(int& v : A){
        v = 0;
    }
    printArray(A, 3);

    return 0;
}
$ g++ experiment.cpp && ./a.out

1 2 3
1 2 3
0 0 0
  • for(auto a : A) この書き方
  • 参照渡しにするなら for(auto& a : A) こう書く。こう書かないと変更は反映されない
  • 逆に、書き換えないときは & を付けない方がいい

【C++】string s = "abcde"として、s[5]を読んでいいの!?いいんです

for(int i = 0; i < s.length(); i++) {
    if(s[i] == 'c' && s[i+1] == 'h');
...
  • というコードを見かけた
  • 配列でやったら範囲エラー
  • 文字列は終端 '\0' なのでOK
  • 読むだけならね。書き換えはダメ

stackoverflow.com

s[-1]も読んでいいんです!

beta.atcoder.jp

  • 配列だとアクセスできるのは 0〜A.size()-1 だけど、文字列なら左右に1つずつ広く読む分にはOKなのね

学び

  • s = "abcde" として、
  • s[-1], s[5] は読む分にはOK