文字列プログラミング演習 (C++)

ex1 文字列変換

説明

長さ n の文字列の場合は、少し変換する必要があります。

まず、この文字列には「Hello World」と同じようにいくつかのスペースが含まれています。次に、この文字列内でスペースで区切られた単語の順序を逆にし、同時に各文字の大文字と小文字を逆にする必要があります。

たとえば、「He​​llo World」は変形後は「wORLD hELLO」になります。

データ範囲: 1≤n≤ 10^{6} 、文字列には大文字の英字、小文字の英字、およびスペースが含まれます。

上級: 空間計算量 O(n)、時間計算量 O(n)

説明を入力してください:

文字列 s とその長さ n(1 ≤ n ≤ 10^{6})が与えられたとします。

戻り値の説明:

変換された文字列を返してください。このトピックでは、指定された文字列が大文字、小文字、およびスペースで構成されていることを確認します。

 アイデアの説明

この質問の文字列には 2 つの要件があります。

1. 大文字と小文字を交換する

文字 s に対して s-'a'+'A' を実行すると、小文字の s を大文字に変換でき、s-'A'+'a' で大文字の s を小文字に変換できます。

for(int i=0;i<n;i++){
    if(s[i]<='Z'&&s[i]>='A')//大写变小写
        res+=s[i]-'A'+'a';
    else if(s[i]>='a'&&s[i]<='z')//小写变大写
        res+=s[i]-'a'+'A';
    else res+=s[i];//空格照抄
}

2. 文字内の単語の順序を逆にする

C++ のリバース関数 reverse() を使用すると、次の 2 つのステップで操作できます。

まず、文字列全体を逆にします。例: as bc は cb sa に変更できます。

次に、操作の後に文字列を実行し、次のようにスペースを区切り単位としてシーケンスを逆にします。 cb sa は bc as に変更できます。

次に、最初に「cb」や「sa」などの各単語を「認識」します。for ループを通じて文字列の最初の位置を記録し、while ループを通じて単語の終了位置を見つけることができます。つまり、Before にスペースが入ります。

for(int i=0;i<n;i++){
    int j=i;//二次反转的起始位置
    while(j<n&&res[j]!=' ')//二次反转的终止位置
        j++;
    reverse(res.begin()+i, res.begin()+j);//二次反转
    i=j;
}

参照コード

#include <algorithm>
#include <string>
class Solution {
public:
   
    string trans(string s, int n) {
        // write code here
        if(n==0)
            return s;
        string res;
        for(int i=0;i<n;i++){
            if(s[i]<='Z'&&s[i]>='A')//大写变小写
                res+=s[i]-'A'+'a';
            else if(s[i]>='a'&&s[i]<='z')//小写变大写
                res+=s[i]-'a'+'A';
            else res+=s[i];//空格照抄
        }
        reverse(res.begin(),res.end());//整个反转
        for(int i=0;i<n;i++){
            int j=i;//二次反转的起始位置
            while(j<n&&res[j]!=' ')//二次反转的终止位置
                j++;
            reverse(res.begin()+i, res.begin()+j);//二次反转
            i=j;
        }
        return res;

    }
};

ex2 最長の共通プレフィックス

説明

n 個の文字列を含むサイズ n の文字列配列 strs を指定すると、文字列配列内の最長の共通プレフィックスを検索し、この共通プレフィックスを返す関数を作成します。

データ範囲:0≤n≤5000、0≤len( strs_{i}) ≤5000

上級: 空間計算量 O(1)、時間計算量 O(n∗len)

アイデアの紹介

垂直横断 

最初の文字列から始めて、最初の文字列の最初の文字を次の各文字列と比較します。この列の文字が同じ場合は、別の文字が見つかるか、特定の文字が見つかるまで 2 番目の列の文字を比較します。終了した文字列のグループ。

for(int i=0;i<strs[0].size();i++){//比较第一个字符串的每一个字符
    for(int j=1;j<strs.size();j++){//纵向比较字符串
        if(strs[0][i]!=strs[j][i]||i==strs[j].size()){//比较后面的每一个字符串
            return strs[0].substr(0,i);//若字符不相同或者长度为最小则返回最长公共前缀
        }
    }
}

ここでは、文字列セグメンテーション関数 substr() を使用する必要があります。関数の構文は次のとおりです。

string substr (size_t pos, size_t len) const;

ここで、 pos はインターセプトされるサブストリングの開始位置を表し、 len はインターセプトされるサブストリングの長さを表します。

他にもいくつかの形式があります。

substr(string str, int a, int b);

str はインターセプトされる文字列
a インターセプトされる文字列の開始位置
b インターセプトされる文字列の長さ

substr(string str, int a) ;

a は、a 番目の文字から始まる後続のすべての文字列をインターセプトするものとして理解できます。

s.substr(pos, n)

s の pos から始まる n 文字のコピーを含む文字列を返します (pos のデフォルト値は 0、n のデフォルト値は s.size() - pos です。つまり、パラメータが追加されない場合は、s 全体が返されます)。 pos の場合、
値が文字列のサイズを超えると、substr 関数は out_of_range 例外をスローします。pos+n の値が文字列のサイズを超えると、substr は n の値を調整します。それを文字列の末尾にのみコピーします

コードリファレンス

class Solution {
public:
    string longestCommonPrefix(vector<string>& strs) {
        // write code here
        if(strs.size()==0)return "";//空串返回空值
        for(int i=0;i<strs[0].size();i++){//比较第一个字符串的每一个字符
            for(int j=1;j<strs.size();j++){//纵向比较字符串
                if(strs[0][i]!=strs[j][i]||i==strs[j].size()){//比较后面的每一个字符串
                    return strs[0].substr(0,i);//若字符不相同或者长度为最小则返回最长公共前缀
                }
            }
        }
        return strs[0];
    }
};

トピックのソース:

最も長い一般的なプレフィックス_Niuke の質問_Niuke.com 

おすすめ

転載: blog.csdn.net/m0_52124992/article/details/131796678