柿子饼同学 发表于 2022-4-26 21:36:03

一个字符串匹配的问题

题目 : 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 = tolower(s);
      }
}
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;
感觉我写的挺对 , 但是输出不尽人意 . 我的代码哪里有问题呢{:10_266:}

傻眼貓咪 发表于 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 = tolower(s);
    }
}
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;
}

柿子饼同学 发表于 2022-4-26 22:53:12

本帖最后由 柿子饼同学 于 2022-4-26 22:54 编辑

傻眼貓咪 发表于 2022-4-26 22:13
稍微更改一下:

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

jackz007 发表于 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 = tolower(s)   ;
}

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:\\\cin>g++ -o x x.c

D:\\\cin>x
To
to be or not to be is a question
2 0

D:\\\cin>x
to
Did the Ottoman Empire lose its power at that time
-1

D:\\\cin>

傻眼貓咪 发表于 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 位置开始匹配。
(四)另外 , 如果函数的参数是一个引用, 可不可以直接传入变量名呢(就像上面的改小写函数)
解:哈哈哈,这就是我觉得你的代码有点奇怪的地方,如你所说,可以的

柿子饼同学 发表于 2022-4-27 13:24:40

jackz007 发表于 2022-4-26 23:21
编译、运行实况:

谢谢回答~

柿子饼同学 发表于 2022-4-27 13:25:10

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

okok谢谢

傻眼貓咪 发表于 2022-4-27 15:30:21

本帖最后由 傻眼貓咪 于 2022-4-27 15:32 编辑

柿子饼同学 发表于 2022-4-27 13:25
okok谢谢

你的代码其实也不正确,cin 只读取单词,不会读取整行。用 getline(cin, str)

傻眼貓咪 发表于 2022-4-27 16:17:39

#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;
}
页: [1]
查看完整版本: 一个字符串匹配的问题