用C/C++编个程序,实现功能:能尽可能多的产生一段回文,(回文由单词组成,单词在某个文件里)
来源:学生作业帮助网 编辑:六六作业网 时间:2024/11/16 13:45:28
用C/C++编个程序,实现功能:能尽可能多的产生一段回文,(回文由单词组成,单词在某个文件里)
用C/C++编个程序,实现功能:能尽可能多的产生一段回文,(回文由单词组成,单词在某个文件里)
用C/C++编个程序,实现功能:能尽可能多的产生一段回文,(回文由单词组成,单词在某个文件里)
#include
#include
#include
#include
#include
#include
using namespace std;
/*
单词字典类
*/
class WordDictory
{
public :
/*
判断字符串 str 的内容是一个单词
单词的定义是:字符串的内容组成为字符 'A'~'Z' , 'a'~'z'
*/
static bool isWord(string str)
{
for(int i=0;i='A'&&str[i]='a'&&str[i]='a' && str[0]wordDictoryFileName.c_str()) ;
if(fin)
{
while(!fin.eof())
{
string str = "";
fin >> str;
// 判断读入的是否是单词
if(isWord(str))
{
this->wordDictory.push_back(str);
// 统计最短单词长度
this-> minWordLength = (this-> minWordLength==0 || this-> minWordLength > str.length() )
? str.length() : this-> minWordLength ;
// 统计最长单词长度
this-> maxWordLength = (this-> maxWordLength==0 || this-> maxWordLength < str.length() )
? str.length() : this-> maxWordLength ;
}
}
fin.close();
// 单词字典排序
sort(this->wordDictory.begin(),this->wordDictory.end());
}
else
{
cerr maxWordLength;
}
/*
判断能否通过字典里面的单词组合,得到 subfix 这样的一个结尾
subfix: 一个要用单词组合出来的结尾
maxUseWordsNum: 组合时能使用的最多单词数目
availablePerWordUsedTime:组合时每个单词能使用的做多次数(哈希表)
isCaseSensitive: 是否大小写敏感(默认不敏感)
*/
bool canMakeTheSubfix(string subfix,int maxUseWordsNum,map &availablePerWordUsedTime,bool isCaseSensitive = false)
{
// 递归终止条件:可以使用的单词数目已经达到上限
if(maxUseWordsNum == 0)
{
return false;
}
// 枚举字典里面的每个单词
for(int i=0;iwordDictory.size();i++)
{
string word = this->wordDictory[i];
// 判断当前单词是否还能使用(使用次数没有达到限制)
if(availablePerWordUsedTime[word] > 0)
{
// 当前单词 word 不比要找的后缀 subfix 短
if(word.length() >= subfix.length())
{
// 计算当前单词和要找的后缀的长度差
int subLenght = word.length() - subfix.length();
// 判断当前单词 word 是否以后缀 subfix 结尾,并作为结果返回
if(compareWords(word.substr(subLenght) , subfix , false) == 0)
{
return true;
}
}
// 当前单词 word 比要找的后缀 subfix 短
else
{
// 计算要找的后缀 subfix 和当前单词 word 的长度差
int subLenght = subfix.length() - word.length();
// 判断后缀 subfix 是否以当前单词 word 结尾
if(compareWords(subfix.substr(subLenght) , word) == 0)
{
// 标记当前单词被使用一次
availablePerWordUsedTime[word]--;
/*
递归
递归时的后缀,为在当前后缀 subfix 的末尾, 减去当前单词 word ,剩下的部分
递归时可以使用的最多单词数 maxUseWordsNum 减一
*/
bool can = canMakeTheSubfix(subfix.substr(0,subLenght),maxUseWordsNum-1,availablePerWordUsedTime,false);
// 回溯
availablePerWordUsedTime[word]++;
if(can)
{
return true;
}
}
}
}
}
return false;
}
private:
string wordDictoryFileName;
vector wordDictory;
int minWordLength;
int maxWordLength;
};
/*
产生单词回文类
*/
class WordPalindrome
{
public:
// 默认的单词文件
static const string DEFAULT_WORDS_FILE_NAME;
// 默认的生成回文保存位置
static const string DEFAULT_WORDS_PALINDROM_FILE_NAME;
// 表示无限的特殊数字,因为这里的数字取值都是正整数,用一个负数表示无限
static const int INIFINITE = -1;
/*
构造函数
minWordsUsedNum:指定产生回文最少使用的单词数,默认 1 个单词
maxWordsUsedNum :指定产生回文最多使用的单词数,默认没有上限(值为-1)
maxPerWordUsedTime:每个单词在回文中能出现的最多次数,默认没有上限(值为-1)
neededWordPalindromeNum: 指定需要产生的回文总数.
当产生的回文数到达这个数目,
或者指定使用的单词数[minWordsUsedNum,maxWordsUsedNum]范围内所有回文都已经产生,但是还没到达这个数目,
停止继续产生回文.
默认产生尽可能多数目的回文(值为-1)
isCaseSensitive:大小写是否敏感,默认不敏感(false)
wordDictoryFileName:指定产生回文是用的单词文件,默认为程序同目录下的 words.txt 文件
wordPalindromeFileName:指定的产生的回文保存文件,默认为程序同目录下的 wordPalindrome.txt 文件
*/
WordPalindrome(int minWordsUsedNum=1,int maxWordsUsedNum=INIFINITE,
int maxPerWordUsedTime = INIFINITE,
int neededWordPalindromeNum = INIFINITE,
bool isCaseSensitive = false,
string wordDictoryFileName=DEFAULT_WORDS_FILE_NAME,
string wordPalindromeFileName=DEFAULT_WORDS_PALINDROM_FILE_NAME)
{
this->minWordsUsedNum = minWordsUsedNum;
this->maxWordsUsedNum = maxWordsUsedNum;
this->maxPerWordUsedTime = maxPerWordUsedTime;
this->neededWordPalindromeNum = neededWordPalindromeNum;
this->isCaseSensitive = isCaseSensitive;
this->wordDictoryFileName = wordDictoryFileName;
this->wordDictory = new WordDictory(this->wordDictoryFileName);
this->wordPalindromeFileName = wordPalindromeFileName;
}
~WordPalindrome()
{
if(this->wordDictory)
{
delete(this->wordDictory);
}
}
/*
开始产生回文
*/
void execute()
{
// 记录开始运行时间
this->startExecuteTime = time(NULL);
// 统计当前已经产生的回文数目
int currentWordPalindromeNum = 0;
// 打开输出产生回文的文件
ofstream foutWordPalindrome (this->wordPalindromeFileName.c_str());
for(
int useWordsNum = this->minWordsUsedNum;
// 使用单词数限制
(useWordsNum < this->maxWordsUsedNum || this->maxWordsUsedNum == INIFINITE)
&&
// 产生回文总数限制
(currentWordPalindromeNum < this->neededWordPalindromeNum || this->neededWordPalindromeNum == INIFINITE)
;
useWordsNum ++
)
{
list wordsBuffer;
getWordPalindrome(useWordsNum,currentWordPalindromeNum,wordsBuffer,foutWordPalindrome);
}
// 关闭文件
foutWordPalindrome.close();
cout