鱼C论坛

 找回密码
 立即注册
查看: 1225|回复: 8

[已解决]一个字符串匹配的问题

[复制链接]
发表于 2022-4-26 21:36:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
题目 : https://www.luogu.com.cn/problem/P1308
我的代码 :
#include <bits/stdc++.h>
using namespace std;
//全部改成小写
void low(string &s){
        for(int i = 0; i < s.size(); i++){
                s[i] = tolower(s[i]);
        }
}
string target, sentence;

int main(){
        ios::sync_with_stdio(false);

        cin >> target >> sentence;
        string &s = sentence;
        string &t = target;
        low(t); low(s);
        //匹配整个单词, 不是一个包含一个的
        target = ' ' + target + ' ';
        sentence = ' ' + sentence + ' ';
        
        if(sentence.find(target) == -1){//第一次匹配不到直接退
                cout << "-1";
                return 0;
        } 
        else{
                int pos = sentence.find(target);
                int c = 0, p = pos; //c是计数器, p是第一次匹配到的位置
                while(pos != -1){
                        c++;
                        pos = sentence.find(target, pos-1);
                }
                cout << c << ' ' << p;
        }
        return 0;
感觉我写的挺对 , 但是输出不尽人意 . 我的代码哪里有问题呢
最佳答案
2022-4-27 08:26:50
柿子饼同学 发表于 2022-4-26 22:53
谢谢回答 , 但是有几个不理解的地方...
之前不是判断过第一次匹不匹配了嘛(22行) , 为什么29行要再看 ...

你的不解的地方:
(一)之前不是判断过第一次匹不匹配了嘛(22行) , 为什么29行要再看一次?
解:这个你可以忽略,因为我没有注意上面,重写了一次匹配。
(二)为啥 c 初始化为 1 就可以?
解:因为如你所说,你上面已经匹配到了至少一次,所以 c 应该从 1 次算起,否则永远少一个。
(三)为啥 34 行 find(target, pos + 1) pos 要加一(我知道是因为加了一个空格, 只是不知道find返回的
值是sentence发现target的第一个字母的位置还是末尾的位置
解:比如 pos 是 13(表示第 13 个位置上发现句子)那么 pos + 1 就是 14,接下来从第 14 位置开始匹配。
(四)另外 , 如果函数的参数是一个引用, 可不可以直接传入变量名呢(就像上面的改小写函数)
解:哈哈哈,这就是我觉得你的代码有点奇怪的地方,如你所说,可以的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-4-26 22:13:35 | 显示全部楼层
稍微更改一下:
#include <bits/stdc++.h>
using namespace std;
//全部改成小写
void low(string& s) {
    for (int i = 0; i < s.size(); i++) {
        s[i] = tolower(s[i]);
    }
}
string target, sentence;

int main() {
    ios::sync_with_stdio(false);

    cin >> target >> sentence;
    string& s = sentence;
    string& t = target;
    low(t); low(s);
    //匹配整个单词, 不是一个包含一个的
    target = ' ' + target + ' ';
    sentence = ' ' + sentence + ' ';

    if (sentence.find(target) == -1) {//第一次匹配不到直接退
        cout << "-1";
        return 0;
    }
    else {
        int pos = sentence.find(target);
        int c = 0, p = pos;
        if (pos != string::npos) { // <---------------------------
            c = 1;                 // <---------------------------
            p = pos;               // <---------------------------
            while (pos != string::npos) { // <---------------------------
                c++;               // <---------------------------
                pos = sentence.find(target, pos + 1); // <---------------------------

            }
        }
        cout << c << ' ' << p;
    }
    return 0;
}

评分

参与人数 1荣誉 +5 鱼币 +5 收起 理由
柿子饼同学 + 5 + 5

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2022-4-26 22:53:12 | 显示全部楼层
本帖最后由 柿子饼同学 于 2022-4-26 22:54 编辑


谢谢回答 , 但是有几个不理解的地方...
之前不是判断过第一次匹不匹配了嘛(22行) , 为什么29行要再看一次
为啥 c 初始化为 1 就可以
为啥 34 行 find(target, pos + 1) pos 要加一(我知道是因为加了一个空格, 只是不知道find返回的
值是sentence发现target的第一个字母的位置还是末尾的位置
感谢大佬
另外 , 如果函数的参数是一个引用, 可不可以直接传入变量名呢(就像上面的改小写函数)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-26 23:21:44 | 显示全部楼层
本帖最后由 jackz007 于 2022-4-26 23:34 编辑
#include <string>
#include <iostream>

using namespace std                                                   ;

//全部改成小写
void low(string & s)
{
        for(int i = 0 ; i < s . size() ; i ++) s[i] = tolower(s[i])   ;
}

int main()
{
        string target , sentence                                      ;
        int c , p , pos                                               ;
        getline(cin , target)                                         ;
        getline(cin , sentence)                                       ;
        low(target)                                                   ;
        low(sentence)                                                 ;
        target = ' ' + target + ' '                                   ;
        sentence = ' ' + sentence + ' '                               ;
        p = pos = sentence . find(target , 0)                         ;
        for(c = 0 ; pos != -1 ; ) {
                c ++                                                  ;
                pos = sentence . find(target , pos + target . size()) ;
        } 
        if(c) cout << c << " " << p << endl                           ;
        else cout << "-1" << endl                                     ;
}
        编译、运行实况:
D:\[00.Exercise]\[C]\cin>g++ -o x x.c

D:\[00.Exercise]\[C]\cin>x
To
to be or not to be is a question
2 0

D:\[00.Exercise]\[C]\cin>x
to
Did the Ottoman Empire lose its power at that time
-1

D:\[00.Exercise]\[C]\cin>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-27 08:26:50 From FishC Mobile | 显示全部楼层    本楼为最佳答案   
柿子饼同学 发表于 2022-4-26 22:53
谢谢回答 , 但是有几个不理解的地方...
之前不是判断过第一次匹不匹配了嘛(22行) , 为什么29行要再看 ...

你的不解的地方:
(一)之前不是判断过第一次匹不匹配了嘛(22行) , 为什么29行要再看一次?
解:这个你可以忽略,因为我没有注意上面,重写了一次匹配。
(二)为啥 c 初始化为 1 就可以?
解:因为如你所说,你上面已经匹配到了至少一次,所以 c 应该从 1 次算起,否则永远少一个。
(三)为啥 34 行 find(target, pos + 1) pos 要加一(我知道是因为加了一个空格, 只是不知道find返回的
值是sentence发现target的第一个字母的位置还是末尾的位置
解:比如 pos 是 13(表示第 13 个位置上发现句子)那么 pos + 1 就是 14,接下来从第 14 位置开始匹配。
(四)另外 , 如果函数的参数是一个引用, 可不可以直接传入变量名呢(就像上面的改小写函数)
解:哈哈哈,这就是我觉得你的代码有点奇怪的地方,如你所说,可以的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-27 13:24:40 | 显示全部楼层
jackz007 发表于 2022-4-26 23:21
编译、运行实况:

谢谢回答~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-4-27 13:25:10 | 显示全部楼层
傻眼貓咪 发表于 2022-4-27 08:26
你的不解的地方:
(一)之前不是判断过第一次匹不匹配了嘛(22行) , 为什么29行要再看一次?
解:这个 ...

okok谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-27 15:30:21 From FishC Mobile | 显示全部楼层
本帖最后由 傻眼貓咪 于 2022-4-27 15:32 编辑
柿子饼同学 发表于 2022-4-27 13:25
okok谢谢


你的代码其实也不正确,cin 只读取单词,不会读取整行。用 getline(cin, str)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-4-27 16:17:39 From FishC Mobile | 显示全部楼层
#include <iostream>
#include <cctype>

void lower(std::string &str) {
        for (char &c: str) c = tolower(c);
}

int main() {

        std::string target;
        std::string sentence;
        
        std::cin >> target;
        getc(stdin);
        std::getline(std::cin, sentence);
        
        lower(target);
        lower(sentence);
        
        int count = 0, pos = 0, p = -1;
        
        if (sentence.find(target) == std::string::npos) {
                std::cout << p;
        }
        else {
                p = pos = sentence.find(target);
                while (pos != std::string::npos) {
                        count++;
                        pos = sentence.find(target, pos+1);
                }
                std::cout << count << " " << p;
        }
        return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-6-10 21:49

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表