tomo_no
@tomo_no (T N)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

文字列の結合(+=だと計算量が異なる?)

解決したいこと

文字列s,tを結合するときにt=t+sとt+=sとするのでは計算量が大きく異なるがそれはなぜですか?

競技プログラミングのZONeエナジー プログラミングコンテスト “HELLO SPACE”のD問題を解いていて発見しました。
以下には2つのコードがありますが、違いは39行目(t = t + s[i] なのか t += s[i] なのか)のみです。サイト上で実行していただけると計算時間が大きく異なっていることが確認できると思います。

該当するソースコード

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;

int main()
{
    string s;
    cin >> s;
    int n = s.size();
    string t = "";
    bool rev = false;
    int t_size = 0;

    for (int i = 0; i < n; i++)
    {
        if (s[i] == 'R')
        {
            rev = !rev;
            continue;
        }
        if (t_size == 0)
        {
            t = t + s[i];
            t_size++;
        }

        else
        {
            if (!rev)
            {
                if (t[t_size - 1] == s[i])
                {
                    t.erase(t_size - 1);
                    t_size--;
                }
                else
                {
                    t = t + s[i];
                    t_size++;
                }
            }

            else
            {
                if (t[0] == s[i])
                {
                    t.erase(0, 1);
                    t_size--;
                }
                else
                {
                    t = s[i] + t;
                    t_size++;
                }
            }
        }
    }
    if (rev)
        reverse(t.begin(), t.end());
    cout << t << endl;
}

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;

int main()
{
    string s;
    cin >> s;
    int n = s.size();
    string t = "";
    bool rev = false;
    int t_size = 0;

    for (int i = 0; i < n; i++)
    {
        if (s[i] == 'R')
        {
            rev = !rev;
            continue;
        }
        if (t_size == 0)
        {
            t = t + s[i];
            t_size++;
        }

        else
        {
            if (!rev)
            {
                if (t[t_size - 1] == s[i])
                {
                    t.erase(t_size - 1);
                    t_size--;
                }
                else
                {
                    t += s[i];
                    t_size++;
                }
            }

            else
            {
                if (t[0] == s[i])
                {
                    t.erase(0, 1);
                    t_size--;
                }
                else
                {
                    t = s[i] + t;
                    t_size++;
                }
            }
        }
    }
    if (rev)
        reverse(t.begin(), t.end());
    cout << t << endl;
}

0

1Answer

t += s[i] の場合には operator+= が使われます。
基本的に append() と同じ内容だと思えばよいと思います。
つまり、既存の t に追加しています。

一方 t = t + s[i]operator+ が使われます。
これは、 ts[i] を連結した新しい string を生成することになります。
その後、その新しい string を t に代入しています。

新しいオブジェクトを生成する分、t = t + s[i] の方の計算時間が大きくなるのだと思います。

0Like

Comments

  1. @tomo_no

    Questioner

    回答ありがとうございます
    重ねての質問となり申し訳ないのですが、どの程度の計算量になるかご存知でしたら教えていただけないでしょうか?
  2. 環境やデータによっても変わってくるので、一概にどの程度違うのかは言えないと思います。
    (特定の環境、データであれば実測するのが一番早いですが、それでも確実とは言えないです)

Your answer might help someone💌