Codeforces 23A You're Given a String...

本文探讨了一道关于寻找字符串中重复子串的最长长度的编程问题,提供了三种不同但有效的解决方法,包括普通遍历、利用vector排序匹配以及使用set进行集合匹配,旨在帮助读者理解并掌握此类问题的不同解题思路。
A. You're Given a String...
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

You're given a string of lower-case Latin letters. Your task is to find the length of its longest substring that can be met in the string at least twice. These occurrences can overlap (see sample test 2).

Input

The first input line contains the string. It's guaranteed, that the string is non-empty, consists of lower-case Latin letters, and its length doesn't exceed 100.

Output

Output one number — length of the longest substring that can be met in the string at least twice.

Examples
input
abcd
output
0
input
ababa
output
3
input
zzz
output
2
其实就是一个字符串的问题,水题一道,但我想跟大家说说不同的做法:
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define REP(i,n) for((i)=0;(i)<(int)(n);i++)
 4 int main(){
 5     int n,i,j,k;
 6     string s;
 7     cin>>s;
 8     n=s.length();
 9     int ans=0;
10     REP(i,n) REP(j,n) if(i<j){//两个字符串首元素位置 
11         for(k=0;;k++) if(i+k>=n||j+k>=n||s[i+k]!=s[j+k]) break;//跑字符串长度,越界或不匹配跳出 
12         ans=max(ans,k);//更新最大值 
13     }
14     cout<<ans<<endl;
15     return 0;
16 }
这是最普通的做法了,O(n^3),其实不到。
这个方法好在第三重循环,写的很妙。
1 for(k=0;;k++) if(i+k>=n||j+k>=n||s[i+k]!=s[j+k]) break;
跑两个字符串的首元素的位置,而不是先跑长度,这个想法很有趣。
之后再跑长度后就可以一位一位跑了,
这样比一个个枚举同样长度的字符串要好很多。
对比一下先跑长度的做法:
#include<bits/stdc++.h>
using namespace std;
int main(){
    string s;
    cin>>s;
    int res=0;
    for(int l=1;l<=s.size();l++){//跑长度 
        vector<string>v; 
        for(int i=0;i+l-1<s.size();i++)
            v.push_back(s.substr(i,l));//把当前长度的字符串扔进vector里 
        sort(v.begin(),v.end());//排序准备匹配 
        for(int i=0;i<v.size()-1;i++)//开始匹配 
            if(v[i]==v[i+1]){//匹配成功,保存长度 
                res=l;
                break;
            }
    }
    cout<<res<<endl;
    return 0;
}
是不是匹配时麻烦很多?
当然,这里通过排序匹配,其实也可以用STL里的Set来做:
#include<bits/stdc++.h>
using namespace std;
int n,m;
string w;
set<string>all;
int main(){
    cin>>w;
    int n=w.size();
    for(int i=n-1;i>0;i--){//跑长度 
        all.clear();//清空set 
        for(int j=0;j+i<=n;j++) all.insert(w.substr(j,i));//将子串插入集合 
        if(all.size()!=n-i+1){//集合里元素个数与总个数不一样,说明有重复,成功! 
            cout<<i<<endl;
            return 0;
        }
    }
    cout<<0<<endl;
    return 0;
} 
是不是也很妙?
总结:本题是水题,但我把水题做出3种解法出来,说明这题质量很好
希望大家在一些优秀的题上不妨多想想,这样信息学水平会提高不少的。
(打比赛时就被这么无聊了,毕竟比赛比谁做的对,不是谁写的更好!)
 



转载于:https://www.cnblogs.com/ybwowen/p/8733062.html

打开链接下载源码: https://pan.quark.cn/s/a4b39357ea24 在Qt框架中,QSerialPort类被视为一个关键组件,用于执行与串行端口之间的通信任务,它具备多样化的功能,涵盖了串口的开启与关闭操作,以及波特率、数据位、停止位和奇偶校验等参数的设定,同时还包括数据的发送和接收功能。在标题和描述中提及的“Qt5的QSerialPort类通过信号槽实现串口读写”,这代表了一种在Qt编程中普遍采用的事件驱动策略,借助信号槽机制,能够便捷地管理串口数据的传输与接收。 1. **QSerialPort类的基础操作**: - 初始化阶段:必须构建一个QSerialPort实例,并为其指定串口名称,例如"/dev/ttyUSB0"。 - 参数配置:利用`setPortName()`、`setBaudRate()`、`setDataBits()`、`setParity()`、`setStopBits()`、`setFlowControl()`等方法,依据具体需求对串口参数进行配置。 - 串口开启/终止:借助`open()`方法启动串口,通过`close()`方法终止串口。务必验证`isOpen()`的返回状态,以确保操作的有效性。 2. **信号槽机制的应用**: - 信号的生成:QSerialPort类中定义了若干信号,诸如`readyRead()`表明有数据可读,`error()`指示出现错误,`bytesWritten()`显示数据已传输等。当这些事件发生时,将触发相应的信号。 - 槽函数的关联:相应地,可以将这些信号与自定义的槽函数相连接,比如,当`readyRead()`信号被激活时,可以调用一个用于处理读取数据的函数。 3. **串口数据...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值