检查字符串是否是拉平德罗姆

Checking whether a String is a Lapindrome or not

本文关键字:罗姆 字符串 是否是 检查      更新时间:2023-10-16

问题是检查给定的字符串是否是 lapindrome(CodeChef(。根据这个问题,Lapindrome被定义为一个字符串,当在中间分割时,给出两个具有相同字符和每个字符相同频率的两半。

我尝试使用下面的代码使用 C++ 来解决问题

#include <iostream>
#include<cstring>
using namespace std;
bool lapindrome(char s[],int len){
int firstHalf=0,secondHalf=0;
char c;
for(int i=0,j=len-1;i<j;i++,j--){
firstHalf += int(s[i]);
secondHalf += int(s[j]);
}
if(firstHalf == secondHalf){
return true;
}
else
return false;
}
int main() {
// your code goes here
int t,len;
bool result;
char s[1000];
cin>>t;
while(t){
cin>>s;
len = strlen(s);
result = lapindrome(s,len);
if(result == true)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
--t;
}
return 0;
}

我取了两个计数变量,它们将存储上半部分和后半部分字符的 ascii 代码的总和。然后比较这两个变量以检查两半是否相等。 我已经在几个自定义输入上尝试了代码,它工作正常。但是在我提交代码后,解决方案似乎是错误的。

将 lapindrome 函数替换为此函数:

bool isLapindrome(std::string str)
{
int val1[MAX] = {0};
int val2[MAX] = {0};
int n = str.length();
if (n == 1)
return true;
for (int i = 0, j = n - 1; i < j; i++, j--)
{
val1[str[i] - 'a']++;
val2[str[j] - 'a']++;
}
for (int i = 0; i < MAX; i++)
if (val1[i] != val2[i])
return false;
return true;
}

示例输出

Input a string here: asdfsasd
The string is NOT a lapindrome.
---
Input a string here: asdfsdaf
The string is a lapindrome.

享受!

你不是在计算字符的频率,只是在计算它们的总和。您可以简单地将字符串分成两半,为两侧的字符频率创建两个映射,例如 std::map 包含每个字符的计数。然后你可以用类似 std::equal 的东西比较两个映射,以检查映射的完全相等性(以查看两半在字符频率方面是否相同(。

与其计算两个数组或映射中字符的频率(在输入字符串的两半中(,实际上将它们也计算在一个数组或映射中就足够了。

为此,必须允许负计数。

示例代码:

#include <iostream>
#include <string>
#include <unordered_map>
bool isLapindrome(const std::string &text)
{
std::unordered_map<unsigned char, int> freq;
// iterate until index (growing from begin) and
// 2nd index (shrinking from end) cross over
for (size_t i = 0, j = text.size(); i < j--; ++i) {
++freq[(unsigned char)text[i]]; // count characters of 1st half positive
--freq[(unsigned char)text[j]]; // count characters of 2nd half negative
}
// check whether positive and negative counts didn't result in 0
// for at least one counted char
for (const std::pair<unsigned char, int> &entry : freq) {
if (entry.second != 0) return false;
}
// Otherwise, the frequencies were balanced.
return true;
}
int main()
{
auto check = [](const std::string &text) {
std::cout << ''' << text << "': "
<< (isLapindrome(text) ? "yes" : "no")
<< 'n';
};
check("");
check("abaaab");
check("gaga");
check("abccab");
check("rotor");
check("xyzxy");
check("abbaab");
}

输出:

'': yes
'abaaab': yes
'gaga': yes
'abccab': yes
'rotor': yes
'xyzxy': yes
'abbaab': no

科里鲁的现场演示

注意:

关于空输入字符串,我有点不确定。如果需要不算作Lapindrome,则需要在isLapindrome()中进行额外的检查。这可以通过更改决赛来实现

return true;

return !text.empty(); // Empty input is considered as false.

你的代码的问题在于,你只比较字符的总和。频率的意思是你必须计算每个字符的出现次数。您可以简单地对两个字符串进行排序和比较,而不是像此处的其他解决方案那样计算地图中的频率。

#include <iostream>
#include <string>
#include <algorithm>
bool lapindrome(const std::string& s) {
// true if size = 1, false if size = 0
if(s.size() <= 1) return (s.size());
std::string first_half = s.substr(0, s.size() / 2);
std::sort(first_half.begin(), first_half.end());
std::string second_half = s.substr(s.size() / 2 + s.size() % 2);
std::sort(second_half.begin(), second_half.end());
return first_half == second_half;
}
// here's a shorter hacky alternative:
bool lapindrome_short(std::string s) {
if (s.size() <= 1) return (s.size());
int half = s.size() / 2;
std::sort(s.begin(), s.begin() + half);
std::sort(s.rbegin(), s.rbegin() + half); // reverse half
return std::equal(s.begin(), s.begin() + half, s.rbegin());
}
int main() {
int count;
std::string input;
std::cin >> count;
while(count--) {
std::cin >> input;
std::cout << input << ": " 
<< (lapindrome(input) ? "YES" : "NO") << std::endl;
}
return 0;
}

现场演示