set<char>(s.begin(), s.end()).size() == s.length()的用法
时间: 2024-05-26 17:13:55 浏览: 6
这行代码的作用是判断字符串s中是否有重复的字符。
具体来说,将字符串s的所有字符放入一个set容器中,由于set容器不允许重复元素存在,因此如果s中有重复的字符,那么在将字符放入set容器时,set容器中就会丢失一些字符,最终set容器的大小就会小于字符串s的长度。因此,如果上述代码中set容器的大小等于字符串s的长度,那么说明字符串s中没有重复的字符。
需要注意的是,这行代码中的set是STL中的一个容器,其用法是将一个序列中的元素按照一定的规则排序,并且去掉重复元素,最终得到一个有序的序列。在这里,我们将字符作为元素放入set容器中,因此代码中使用了模板参数为char的set容器。另外,s.begin()和s.end()分别表示字符串s的起始位置和终止位置,用于标识需要放入set容器中的元素范围。
相关问题
优化这段代码#include <iostream> #include <iomanip> #include <stdio.h> #include <fstream> #include <string> #include <algorithm> #include <unordered_map> #include <map> #include <stack> #include <set> #include <vector> using namespace std; struct Production { char left; // 产生式的左部非终结符 string right; // 产生式的右部字符串 }; map<char, set<char>> firstSets; int main() { vector<Production> productions; ifstream infile("grammar.txt"); char left; string right; while (infile >> left >> right) { productions.push_back({ left, right }); } for (auto p : productions) { char left = p.left; string right = p.right; char firstChar = right[0]; if (isupper(firstChar)) { // 如果是非终结符 // 计算非终结符的first集合 set<char> firstSet = firstSets[firstChar]; for (int i = 0; i < right.length(); i++) { char ch = right[i]; if (isupper(ch)) { // 如果是非终结符 firstSet.insert(firstSets[ch].begin(), firstSets[ch].end()); if (firstSets[ch].find('$') == firstSets[ch].end()) { // 如果该非终结符没有空串 break; } } else { // 如果是终结符 firstSet.insert(ch); break; } } firstSets[left].insert(firstSet.begin(), firstSet.end()); } else { // 如果是终结符 firstSets[left].insert(firstChar); } } for (auto p : productions) { char left = p.left; cout << "First(" << left << ") = {"; for (auto ch : firstSets[left]) { cout << ch << ", "; } cout << "}" << endl; } }使得能正确求出frist集
以下是优化后的代码:
```c++
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <set>
using namespace std;
// 产生式结构体
struct Production {
char left; // 产生式的左部非终结符
string right; // 产生式的右部字符串
};
// 计算first集合
set<char> calcFirstSet(char ch, const vector<Production>& productions, map<char, set<char>>& firstSets) {
// 如果该字符已经计算过first集合,直接返回
if (firstSets.find(ch) != firstSets.end()) {
return firstSets[ch];
}
set<char> result;
// 遍历所有产生式,查找该字符作为左部的产生式
for (auto p : productions) {
if (p.left == ch) {
// 如果右部第一个字符是终结符,则加入该字符
if (!isupper(p.right[0])) {
result.insert(p.right[0]);
}
// 如果右部第一个字符是非终结符,则计算该非终结符的first集合
else {
set<char> subResult = calcFirstSet(p.right[0], productions, firstSets);
result.insert(subResult.begin(), subResult.end());
// 如果该非终结符的first集合中包含空串,则计算下一个字符的first集合
for (int i = 1; i < p.right.length() && subResult.find('$') != subResult.end(); i++) {
if (!isupper(p.right[i])) {
result.insert(p.right[i]);
break;
} else {
subResult = calcFirstSet(p.right[i], productions, firstSets);
result.insert(subResult.begin(), subResult.end());
}
}
}
}
}
// 将计算得到的first集合插入到map中
firstSets.insert(make_pair(ch, result));
return result;
}
int main() {
vector<Production> productions;
ifstream infile("grammar.txt");
// 读取产生式
char left;
string right;
while (infile >> left >> right) {
productions.push_back({ left, right });
}
map<char, set<char>> firstSets;
// 计算每个非终结符的first集合
for (auto p : productions) {
if (isupper(p.right[0])) {
set<char> result = calcFirstSet(p.left, productions, firstSets);
firstSets.insert(make_pair(p.left, result));
} else {
firstSets.insert(make_pair(p.left, set<char>{p.right[0]}));
}
}
// 输出每个非终结符的first集合
for (auto p : productions) {
char left = p.left;
cout << "First(" << left << ") = {";
for (auto ch : firstSets[left]) {
cout << ch << ", ";
}
cout << "}" << endl;
}
}
```
优化后的代码主要是将计算first集合的部分提取出来,封装成了一个函数`calcFirstSet`。在计算每个非终结符的first集合时,只需调用该函数进行计算即可。同时,在计算非终结符的first集合时,使用了递归的方式,可以很方便地计算出包含空串的情况。
import java.util.LinkedList; import java.util.Scanner; import java.util.TreeSet; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s = sc.nextLine(); System.out.println(getResult(s)); } public static String getResult(String s) { StringBuilder sb = new StringBuilder(); LinkedList<TreeSet<Character>> eqs = new LinkedList<>(); boolean isOpen = false; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (c == '(') { isOpen = true; eqs.add(new TreeSet<>()); } else if (c == ')') { isOpen = false; if (eqs.getLast().size() == 0) eqs.removeLast(); } else { if (!isOpen) sb.append(c); else eqs.getLast().add(c); } } outer: while (true) { for (int i = 0; i < eqs.size(); i++) { for (int j = i + 1; j < eqs.size(); j++) { if (canCombine(eqs.get(i), eqs.get(j))) { eqs.get(i).addAll(eqs.get(j)); eqs.remove(j); continue outer; } } } break; } char[] cArr = sb.toString().toCharArray(); for (TreeSet<Character> eq : eqs) { Character t = eq.first(); for (int i = 0; i < cArr.length; i++) { if (eq.contains(cArr[i])) cArr[i] = t; } } String ans = new String(cArr); return ans.length() == 0 ? "0" : ans; } public static boolean canCombine(TreeSet<Character> set1, TreeSet<Character> set2) { for (char c = 'a'; c <= 'z'; c++) { char uc = (char) (c - 32); if ((set1.contains(c) || set1.contains(uc)) && (set2.contains(c) || set2.contains(uc))) { return true; } } return false; } }翻译成C++
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
string getResult(string s) {
string ans;
vector<set<char>> eqs;
bool isOpen = false;
for (int i = 0; i < s.length(); i++) {
char c = s[i];
if (c == '(') {
isOpen = true;
eqs.push_back(set<char>());
} else if (c == ')') {
isOpen = false;
if (eqs.back().empty()) eqs.pop_back();
} else {
if (!isOpen) ans += c;
else eqs.back().insert(c);
}
}
while (true) {
bool combined = false;
for (int i = 0; i < eqs.size(); i++) {
for (int j = i + 1; j < eqs.size(); j++) {
if (canCombine(eqs[i], eqs[j])) {
eqs[i].insert(eqs[j].begin(), eqs[j].end());
eqs.erase(eqs.begin() + j);
combined = true;
break;
}
}
if (combined) break;
}
if (!combined) break;
}
for (char& c : ans) {
for (const set<char>& eq : eqs) {
char t = *eq.begin();
if (eq.count(c)) c = t;
}
}
return ans.empty() ? "0" : ans;
}
bool canCombine(const set<char>& set1, const set<char>& set2) {
for (char c = 'a'; c <= 'z'; c++) {
char uc = toupper(c);
if ((set1.count(c) || set1.count(uc)) && (set2.count(c) || set2.count(uc))) {
return true;
}
}
return false;
}
int main() {
string s;
getline(cin, s);
cout << getResult(s) << endl;
return 0;
}
相关推荐
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)