リンク:https://ac.nowcoder.com/acm/problem/16644
ソース:牛客网
#include<bits/stdc++.h>
using namespace std;
string solve(char b,char e,int p1,int p2,int p3)
{
if(e-b==1)return "";
if(!(isalpha(b)&&isalpha(e)&&b<e||isdigit(b)&&isdigit(e)&&b<e))
return "-";
string ans="";
for(char i=b+1;i<e;i++)
{
for(int j=1;j<=p2;j++)
{
ans+=i;
}
}
if(p1==2&&isalpha(b))
{
for(int i=0;i<ans.length();i++)
{
ans[i]=ans[i]-'a'+'A';
}
}
if(p1==3)
{
for(int i=0;i<ans.length();i++)
ans[i]='*';
}
if(p3==2){
reverse(ans.begin(),ans.end());
}
return ans;
}
int main()
{
int p1,p2,p3;
cin>>p1>>p2>>p3;
string a;
cin>>a;
string ans="";
for(int i=0;i<a.length();i++)
{
if(a[i]=='-'&&i-1>=0&&i+1<a.length())
{
ans+=solve(a[i-1],a[i+1],p1,p2,p3);
}
else
{
ans+=a[i];
}
}
cout<<ans<<endl;
return 0;
}
- ' - ' が出現すると、文字列を展開する操作が繰り返されることに気付いたので、関数を作成することを検討できます。
- 文字列を反復処理する方法は、文字列を後ろに移動させることですが、これは明らかに面倒ですし、区間の長さを計算すると複雑になります。最適な方法は、答えを格納するために別の文字列 ans を作成することです。
- もし a [i] が ' - ' でない場合、ans に直接追加します。
- ' - ' の場合は、展開された文字列を追加します。
- どのように展開するか?まず、無効な場合を排除します。
- 最初の無効な場合は、"a-b"->"ab"、"2-3"->"23" などです。この場合、文字または数字であるかどうかに関係なく、後の文字の ASCII コードが前の文字よりも 1 大きいことを統一的に理解できます。つまり、e-b == 1 の場合、空の文字列 "" を返します(e は ' - ' の前の文字を表し、b は ' - ' の後の文字を表します)。
- "ハイフンの両側が小文字または数字であり、ASCII コードの順序に従って、ハイフンの右側の文字が厳密に左側の文字よりも大きい場合。" 逆の面から入り、前の文字後の数字前の数字後の文字などになります。
そして、ans を書く
for(char i=b+1;i<e;i++) { for(int j=1;j<=p2;j++) { ans+=i; } }
このループは非常に巧妙で、最初のレベルはどれを解決するか、2番目のレベルはいくつ解決するかです。
次に、p1=2**であり、**文字である場合、完成した小文字を大文字に変換します。大文字は気にしなくてもいいですが、ここではtoupper関数を呼び出すこともできます(ここで注意する必要がありますが、これは<mark class="hltr-orange">文字であることを確認する必要があります</mark>、私はここでミスをしました。)
p1=3は問題ありません
最後に、reverse関数を呼び出して反転します。
上記のコードには誤りがあります。1. 先頭と末尾の' - '、例えば“-a-d-”
```c++
if(a[i]=='-'&&i-1>=0&&i+1<a.length())
{
ans+=solve(a[i-1],a[i+1],p1,p2,p3);
}
特殊なケースの考慮
- 先頭と末尾の ' - '、例えば “-a-d-”
- 連続する ' - '、例えば “---” この行のコードはこの問題を解決します
(isalpha(b)&&isalpha(e)&&b<e||isdigit(b)&&isdigit(e)&&b<e))
- 数字と文字の間の ' - '、例えば “1-a”
- ' - ' の左側の文字が右側の文字よりも大きい場合、例えば “d-a”