此题目为《程序员》杂志第11期算法擂台题目
从键盘输入一个长度为n的字符串,交换相邻两个字符的位置,判断该字符串是否可以经过有限次交换变成回文串,如果可以,输出交换次数,如果不可以,则输出“Impossible”。
我给出下面算法的C++程序解法,但是不知道这个程序是否可以保证所得的交换次数是否可以达到最优,也就是经过最少次数交换,变成回文串。仅供参考,如有更好的想法,CALL ME!大家一起研究。
程序代码如下:
#include <iostream>
#include <string>
using namespace std;
class huiwen //定义给定字符串类
{
private:
string s;
int len;
public:
huiwen(string str,int len1):s(str),len(len1)
{}
int panduan();
int count();
};
int main()
{
int rez,n=0,no=0;
string s1;
cin>>n;
cin>>s1;
huiwen a1(s1,n);
rez=a1.panduan();
if(rez==0)
{
//cout<<"可以变换。"<<endl;
no=a1.count();
cout<<no<<endl;
}
else
cout<<"Impossible"<<endl;
return 0;
}
int huiwen::count()
{
char *c=new char[len];
char temp_char=' ';
int i=0,j=0,count=0,no=0,k;
for(i=0;i<len;i++)
{
*(c+i)=s[i];
//cout<<"c="<<*(c+i)<<endl;
}
*(c+len)='/0';
for(i=0;i<=len/2;i++)
{
/*for(k=0;k<len;k++)
{
cout<<*(c+k);
}
cout<<endl;*/
for(j=len-1-i;j>=i;j--)
{
if(*(c+i)!=*(c+j))
{
continue;
}
else
{
//cout<<"i和j"<<i<<" "<<j<<endl;
if(i!=j)
{
no=j;
break;
}
else
{
//cout<<"检索序号相等为:"<<i<<endl;
return count;
}
}
}
if(i>j)
{
//cout<<"越界。"<<i<<endl;
return count;
}
temp_char=*(c+no);
//cout<<"和"<<i<<"相同的字符出现在"<<no<<endl;
for(j=no;j<len-i-1;j++)
{
*(j+c)=*(c+j+1);
count++;
}
//cout<<"移动次数:"<<count<<endl;
*(c+j)=temp_char;
}
return count;
}
int huiwen::panduan()
{
int *a=new int[len];
char *b=new char[len];
int j,m=0,c=0,i,sig=0;
for(int i=0;i<s.length();i++)
{
for(j=0;j<m;j++)
{
if(s[i]==*(b+j))
{
sig=1;
break;
}
else
sig=0;
}
if(sig==1)
continue;
*(b+m)=s[i];
m++;
*(b+m)='/0';
}
//cout<<"m="<<m<<endl;
for(j=0;j<m;j++)
{
*(a+j)=0;
//cout<<"b="<<b[j]<<endl;
}
*(a+j)='/0';
for(j=0;j<m;j++)
{
for(i=0;i<s.length();i++)
{
if(*(b+j)==s[i])
(*(a+j))++;
}
}
for(j=0;j<m;j++)
{
//cout<<*(a+j)<<endl;
if(((*(a+j))%2)!=0)
c++;
}
//cout<<"c="<<c<<endl;
if(c>1)
return 1; //可变换成回文
else
return 0; //不可变换
}