我写了以下函数来返回no。从两个字符串中删除字符以使其成为字谜。
int number_needed(string a, string b) {
static int c;
for(int i=0;i<=a.length();i++) //loop over string a
{ char ch=a[i];
int found=b.find(ch);
if( found==string::npos) //if character at a[i] not found in b
{
a.erase(i,1); //delete character in a[i]
c++; //inc. count c
}
}
for(int i=0;i<=b.length();i++) // repeat above looping for b string
{ char ch=b[i];
int found=a.find(ch);
if( found==std::string::npos)
{
b.erase(i,1);
c++;
}
}
return c; //finaly return no. of char. deleted
}
我想知道我是否做得对不对,以及我的想法在问题的背景下是否合适。 另外,您是否可以让我理解以下代码解决同一问题。
int number_needed(string a, string b) {
auto count = 0;
vector<int> freq(26, 0);
for (auto c : a) { ++freq[c - 'a']; }
for (auto c : b) { --freq[c - 'a']; }
for (auto val : freq) { count += abs(val); }
return count;
}
答案 0 :(得分:1)
回答关于主题的第二部分:
vector<int> freq(26, 0);
此向量将保存字符串中字母的出现次数。
for (auto c : a) { ++freq[c - 'a']; }
逐字逐句查看字符串。如果您不熟悉google的for
语法新内容,那么基本上就意味着foreach letter c in string a
。 auto
部分告诉编译器从迭代的东西推断迭代器的类型 - 在这种情况下为字符串a
。
c-'a'
将字母转换为索引。所有字母都连续出现在ASCII字符表中(char到int的映射),因此删除第一个字母“a”会将其更改为0到26之间的索引。请注意,这仅适用于小写字母:{转换为整数时,{1}} = 0,'a'-'a'
= 1等等。因此,每当我们看到它时,我们通过在char向量中加1来计算字符串中字母的出现次数。
'b'-'a
在第二个字符串上执行相同操作,此次删除频率。如果for (auto c : b) { --freq[c - 'a']; }
中的字母出现次数较多,则该字母的a
将为正数超出正数,如果在freq
中出现更多且具有适当的超额,则为负数,或者为0。
b
总结过度 - 绝对值处理来自 for (auto val : freq) { count += abs(val); }
的负超额。
正如TheGreatContini注意到的那样,你不会保留重复的数量。