- C 实现
// -*- coding: utf-8 -*-
// @ Date : 2022/5/20 13:14
// @ Author : RichardLau_Cx
// @ file : Richard.c
// @ IDE : Dev-C++
// @ Source : luogu
#include <stdio.h>
#include <ctype.h>
#include <string.h>
int main() {
char string1[10];
char string2[1000000];
char c;
int i, j;
int flag;
int p = 0; // 子串第一次全匹配时出现的首字母位置
int num = 0; // 累计相同子单词个数
int count = 0; // 字符串2总长度
int len1, len2;
scanf("%s", string1); // 读取字符串1
// 读取字符串2(包括了空格、回车、换行、文件末等的判断)
while ((c = getchar()) != EOF) {
// printf(" -- %c -- ", c);
if (c != '\r' && c != '\n')
string2[count++] = c;
}
while (!isalpha(string2[count-1])) // C 库函数 void isalpha(int c) 检查所传的字符是否是字母。
count--;
string2[count] = '\0'; // 补字符串尾部结束特征
len1 = strlen(string1);
len2 = strlen(string2);
// 将两个字符串中字母分别转化为大写
for(i=0; i < len1; i++) {
if (isalpha(string1[i]) && string1[i] >= 'a' && string1[i] <= 'z')
string1[i] = 'A' + string1[i] - 'a'; // 转化首字母对象,加上“相对偏移量”,即转化后的字母
}
for (i=0; i < len2; i++) {
if (isalpha(string2[i]) && string2[i] >= 'a'&& string2[i] <= 'z')
string2[i] = 'A' + string2[i] - 'a';
}
// 核心算法
for (i=0; i < len2; i++) {
flag = 0;
for (j=0; j < len1; j++) {
// 从字符二的i位置,比j个长度
if (string2[i+j] == string1[j]) {
flag = 1; // 相等
} else {
flag = 0; // 不相等
break;
}
}
if (flag == 1) {
// 持续匹配皆相同时
if (string2[i+len1] == ' ' || i+len1 == count) {
if (i == 0 || string2[i-1] == ' ') { // i位于单词开头处
num ++;
if (num == 1) {
p = i;
}
}
}
}
}
if (num > 0) {
// 含匹配子串
printf("%d %d\n", num, p);
} else {
printf("-1\n");
}
// printf("%s\n", string1);
// printf("%s", string2);
}
- C++ 实现
// -*- coding: utf-8 -*-
// @ Date : 2021/5/20 13:14
// @ Author : RichardLau_Cx
// @ file : Richard.cpp
// @ IDE : Dex-C++
// @ Source : luogu
/*
待优化:
1. 时间复杂度较高,易超时(RE: runtime error);
2. 个别数据未考虑周全(WA:wrong answer)。
*/
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
using namespace std;
int main(void) {
string word; // 输入单词
string sentence; // 输入句子
int wLen, sLen;
int j; // 单词字母索引位置
// int frequency=0; // 单词出现的频率
int position[99]; // 单词出现位置的数组
queue<int> pQ; // 单词出现位置的队列
int first; // 返回第一个位置信息
sentence[-1] = ' '; // 将主串再左边的一个位置赋值为空格,便于判断
// cin >> word;
getline(cin, word);
getline(cin, sentence); // 解决cin读取到空格即结束的问题
// bool temp =
// cout << "word: " << word << " sentence[2]:---" << (sentence[2] < 'A') << "---" << endl;
wLen = word.size(); // 得到单词的长度
sLen = sentence.length(); // 得到句子的长度
// 或者strlen()
for (int i=0; i < sLen; i++)
{
for (j=0; j < wLen; j++)
{
// cout << "word[j]: " << word[j] << " sentence[i]: " << sentence[i] << " abs(word[j] - sentence[i]): " << abs(word[j] - sentence[i]) << endl;
if (word[j] == sentence[i] || abs(word[j] - sentence[i]) == 32)
{
// 字母相等,或者互为大小写
// cout << "true!" << endl;
i++; // 主串也相应移动
}
else
{
break;
}
}
sentence[-1] = ' '; //TODO 很奇怪,-1的位置为什么突然成了字母'e'了?目前只能暂时人为操作一下
// cout << "i: " << i << " i-wLen-1: " << i-wLen-1 << " sentence[i-wLen-1]: " << sentence[i-wLen-1] << " sentence[i]: " << sentence[i] << endl;
if (j == wLen && ((sentence[i-wLen-1] < 'A') || sentence[i-wLen-1] > 'z') && ((sentence[i] < 'A') || sentence[i] > 'z'))
{ // 单词需要完全匹配,不能是包含关系,保证前后不是字母
pQ.push(i-wLen); // 将匹配到的起始位置入队
// frequency++;
// cout << "j: " << j << " i: " << i << endl;
}
else
{
i -= j-1; // 比匹配之前的位置后一个
}
}
// first = pQ.pop();
first = pQ.front();
if(pQ.size())
{
cout << pQ.size() << ' ' << first << endl;
}
else
{
cout << -1 << endl;
}
// cout << "pQ.size(): " << << endl;
return 0;
}