题目:如果一个单词通过循环右移获得的单词,我们称这些单词都为一种循环单词。 例如:picture 和 turepic 就是属于同一种循环单词。 现在给出n个单词,需要统计这个n个单词中有多少种循环单词。
输入描述:
输入包括n+1行: 第一行为单词个数n(1 ≤ n ≤ 50) 接下来的n行,每行一个单词word[i],长度length(1 ≤ length ≤ 50)。由小写字母构成
输出描述:
输出循环单词的种数
输入例子:
5 picture turepic icturep word ordw
输出例子:
2
-题目分析
按照题目要求,要统计单词种类,只需要解决两个子问题:
1.如何判断两个单词是不是循环单词
2.怎样把几个同类单词记做一种
基于划分出来的两个子问题,我们可以用一个vector<string>放单词,再用一个vector<bool>表示当前单词是不是一种新单词。
至少有一种单词就是第一个单词,所以下标curWord从1开始遍历vector<string>,循环内部从0到curWord每一种新单词都和curWord比较,如果是循环单词,就把curWord标记为不是新单词。
-代码
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<vector>
using namespace std;
//判断left和right是不是同一种单词的循环词
bool IsCirStr(string left, string right)
{
if (left == right)
return true;
size_t subRight = 0;
size_t subLeft = 0;
bool flag = true;
for (size_t idx = 0; idx < left.length() - 1; idx++)
{
flag = true;
for (subRight = idx + 1, subLeft = 0; subRight < left.length(); subRight++, subLeft++)
{
if (left[subLeft] != right[subRight])
{
flag = false;
break;
}
}
if (flag)
{
for (subRight = 0; subRight <= idx; subRight++, subLeft++)
{
if (left[subLeft] != right[subRight])
flag = false;
}
}
if (flag)
return true;
}
return false;
}
int main()
{
int n = 0;
vector<string> strList;
vector<bool> NewWord;
cin >> n;//单词个数
for (int idx = 0; idx < n; idx++)
{
string inFromUser;//输入单词
cin >> inFromUser;
strList.push_back(inFromUser);//存入strList
NewWord.push_back(true); //表示是和其他单词没关系的一种单词,默认是新单词
}
int kinds = 1;//至少有一种单词
for (int curWord = 1; curWord < n; curWord++)//顺strList遍历
{
for (int wordIdx = 0; wordIdx < curWord; wordIdx++)//每次把curWord和前面所有词比较
{
if (NewWord[curWord] == true && strList[curWord].length() == strList[wordIdx].length())
{//curWord不是某单词同类词并且curWord和wordIdx长度相等才进入
if (IsCirStr(strList[curWord], strList[wordIdx]))//判断是不是同一种词
{
//标记wordIdx指向的词是curWord的循环单词,标为false放止重复计数
NewWord[curWord] = false;
break;
}
}
}
if (NewWord[curWord] == true)
kinds++;//统计单词种类
}
cout << kinds << endl;
system("pause");
return 0;
}