今天做力扣一道简单的字符串的题目时,使用了无序图来映射int与string的关系。
原题链接917. Reverse Only Letters
917. Reverse Only Letters
Given a string S, return the “reversed” string where all characters that are not a letter stay in the same place, and all letters reverse their positions.
Example 1:
Input: “ab-cd”
Output: “dc-ba”
Example 2:
Input: “a-bC-dEf-ghIj”
Output: “j-Ih-gfE-dCba”
Example 3:
Input: “Test1ng-Leet=code-Q!”
Output: “Qedo1ct-eeLg=ntse-T!”
原来的代码
class Solution {
string ans,temp;
unordered_map<int,string> pos;
public:
string reverseOnlyLetters(string s) {
if(!s.size()) return ans;
for(int i=0;i<s.size();i++){
if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z')) ans+=s[i];
else{
temp=s[i];
pos[i]=temp;
}
}
reverse(ans.begin(),ans.end());
for(unordered_map<int,string>::iterator it=pos.begin();it!=pos.end();it++){
temp=ans;
temp.insert(it->first,it->second);
ans=temp;
}
return ans;
}
};
说到这,本题又是一种类型的题目,即给定的数据中包含了两种不同类型的数据,且对于不同类型的数据的处理不同。本类问题总结
本题中,对于串中的字符,要翻转,而其余的符号要保持原来的顺序。
思路就是,开一个string ans与一个unordered_map < int,string> pos。在遍历给定的串时,使用ans另存原串中的字母字符,注意,这是按照顺序遍历的,所以存下来的字符的顺序还是原来的在串中的顺序。使用pos记录在串中,i位置上的非字母字符。
比如"a-bC-dEf-ghIj",一遍遍历之后,ans中为“abCdEfghIj”,而无序图中,存储了1->“-”,4->“-”,8->“-”。
在之后,使用STL的revers 将ans反转,也就是,此时,字母字符已经按照题目的要求是反转的了,但是,还缺少了原来串中的非字母字符。
这就要用到string的insert函数,注意string 的insert函数,其有两种使用方法,总结如下
//第一种insert(pos,string);
string str="abcdef",str2="opq";
str.insert(3,str2);
将str2插入在str1的pos号位置上。
注意点,第一个参数必须是在[0,str.size() ]之间。
第二个参数必须是string的变量或者常量,不可以是字符类型的变量或者常量。即使是str[0]也不可以。
//第二种insert(it,it1,it2)
string str="abcdef",str2="opq";
str.insert(str.begin()+3,str2.begin(),str2.end());
将str2的[str2.begin(),str2.end() )范围内的元素插入在str1的it处。这里 it,it1,it2必须是迭代器。
本题使用了第一种插入的方法。所以在定义无序图时,是int->string,而不是int-> char,虽然是一个一个的字符。
思路不错,但是本题提交之后就是答案不正确。
调试了半天。还以为思路出错了。
怎么都不对,oj上不能调试,当我将相同的原串数据放到codeblocks上在运行一遍代码时,
#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_map>
using namespace std;
string ans,temp;
unordered_map<int,string> pos;
int main()
{
string s="a-bC-dEf-ghIj";
for(int i=0;i<s.size();i++){
if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z')) ans+=s[i];
else{
temp=s[i];
pos[i]=temp;
}
}
reverse(ans.begin(),ans.end());
for(unordered_map<int,string>::iterator it=pos.begin();it!=pos.end();it++){
ans.insert(it->first,it->second);
}
cout<<ans;
return 0;
}
//运行结果
j-Ihg-fEdC-ba
发现还是不对,所以我想着将无序图中的内容打印出来,于是在第二个for循环里面加了一句话
#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_map>
using namespace std;
string ans,temp;
unordered_map<int,string> pos;
int main()
{
string s="a-bC-dEf-ghIj";
for(int i=0;i<s.size();i++){
if((s[i]>='a'&&s[i]<='z')||(s[i]>='A'&&s[i]<='Z')) ans+=s[i];
else{
temp=s[i];
pos[i]=temp;
}
}
reverse(ans.begin(),ans.end());
for(unordered_map<int,string>::iterator it=pos.begin();it!=pos.end();it++){
ans.insert(it->first,it->second);
cout<<it->first<<" "<<it->second<<endl;//打印无序图
}
cout<<ans;
return 0;
}
//运行结果
8 -
4 -
1 -
j-Ihg-fEdC-ba
恍然大悟
在遍历原来的串时,往无序图里面插入一对对的映射时,是按照遇到非字母字符的顺序插入的,但是,在之后,顺序竟然颠倒了,这也就是为什么出错的原因。 存储顺序和插入顺序不同。
再写个小例子测试一下
#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_map>
using namespace std;
unordered_map<int,string> pos;
int main()
{
pos[10]="a";
pos[99]="b";
pos[1]="c";
for(unordered_map<int,string>::iterator it=pos.begin();it!=pos.end();it++){
cout<<it->first<<" "<<it->second<<endl;
}
return 0;
}
运行结果
可以发现,在代码中插入数据是,插入的顺序为10、99、1,然而存储时,却是1、99、10。
所以,无序图中的存储与插入顺序相反,类似于栈,后进后出。 无序图中的存储与插入顺序不同,那么是不是反序呢?再看一个例子
#include <bits/stdc++.h>
using namespace std;
unordered_map<int, int> mp;
int main()
{
for (int i = 0; i < 10; i++) {
mp[i] = i;
}
for (auto [x, y] : mp) {
cout << x << " ";
}
return 0;
}
运行结果
9 8 7 6 1 0 2 3 4 5
可以看到,按照0 ~ 9 进行插入,存储时不是0~9,也不是9 — 0。不是正序,也不是反序。
实在是坑!!!