Combine String模拟

本文介绍了一种检查字符串cc是否可以通过组合字符串aa和bb形成的算法。提供了两种解题思路及其实现代码,一种是通过直接模拟的方式,另一种是采用动态规划的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Given three strings aa, bb and cc, your mission is to check whether cc is the combine string of aa and bb. 
A string cc is said to be the combine string of aa and bb if and only if cc can be broken into two subsequences, when you read them as a string, one equals to aa, and the other equals to bb. 
For example, ``adebcf'' is a combine string of ``abc'' and ``def''. 
Input
Input file contains several test cases (no more than 20). Process to the end of file. 
Each test case contains three strings aa, bb and cc (the length of each string is between 1 and 2000). 
Output
For each test case, print ``Yes'', if cc is a combine string of aa and bb, otherwise print ``No''. 
Sample Input
abc
def
adebcf
abc
def
abecdf
Sample Output
Yes
No

Hint

题意:

给定a,b,c三个串,问c能否按序分成a和b串,不要求连续。
解题思路1:
直接模拟,1.统计处a,b,c串各个字符出现的次数,看a,b串的某个字符出现次数的和是否与c串中的相等。
2.从头往后扫描c串,看是否能按序找到a,b串。

思路2:

f[i][j]表示第一个字符串用了前i个位置(第i个位置已匹配),第二个字符串的前j个位置(第j个位置已匹配)
是否可以对c串成功匹配(成功匹配则必然会匹配到c串的前i+j个位置)。
f[i][j]==1则表示可以成功匹配
f[i][j]==0则表示无法成功匹配

显然,初始只有f[0][0]==1
所以,我们有——
f[i][j]= f[i-1][j]&&(a[i]==c[i+j])
|| f[i][j-1]&&(b[j]==c[i+j])
这样,最终f[n][m]==1则为Yes否则为No

思路1代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<map>
using namespace std;
map<char,int>ma,mc;
int main()
{
    string a,b,c;
   while(cin>>a>>b>>c)
   {
       ma.clear();
       mc.clear();
       int lena=a.length();
       int lenb=b.length();
       int lenc=c.length();
       for(int i=0;i<lena;i++)
       {
           ma[a[i]]++;
       }
       for(int i=0;i<lenb;i++)
       {
           ma[b[i]]++;
       }
       int x=0,y=0;
       for(int i=0;i<lenc;i++)
       {
           mc[c[i]]++;
           if(x<lena&&c[i]==a[x])
            x++;
           if(y<lenb&&c[i]==b[y])
           y++;
       }
       map<char,int>::iterator it;
       int flag=1;
       for(it=mc.begin();it!=mc.end();it++)
       {
           if(mc[it->first]!=ma[it->first])
           {
               flag=0;
               break;
           }
       }
       if(flag)
       {
           if(x==lena&&y==lenb)
           {
               printf("Yes\n");
           }
           else
            printf("No\n");
       }
       else
        printf("No\n");
   }
}

思路2代码:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
#define bitnum(a) __builtin_popcount(a)
using namespace std;
const int N = 2005;
const int M = 120;
const int inf = 1600000000;
const int mod = 2009;
char a[N],b[N],c[N];
int dp[N][N];
int main()
{
    int i,j,n,m,k;
    while(~scanf("%s",a+1))
    {
        memset(dp,0,sizeof(dp));
        scanf("%s",b+1);
        scanf("%s",c+1);
        n=strlen(a+1);
        m=strlen(b+1);
        k=strlen(c+1);
        if(n+m!=k)
        {
            puts("No");
            continue;
        }
        dp[0][0]=1;
        for(i=0;i<=n;i++)
            for(j=0;j<=m;j++)
            {
                if(i>0&&c[i+j]==a[i])
                    dp[i][j]|=dp[i-1][j];
                if(j>0&&c[i+j]==b[j])
                    dp[i][j]|=dp[i][j-1];
            }
        /*for(i=0;i<=n;i++)
        {
            for(j=0;j<=m;j++)
                printf("%d ",dp[i][j]);
            puts("");
        }*/
        if(dp[n][m])
            puts("Yes");
        else
            puts("No");
    }
    return 0;
}


Combine 框架中,Publisher 是数据流的起点,负责发出值(value)和完成事件(completion)。常见的 Publisher 类型包括以下几种: ### 1. `Just` `Just` 是最简单的 Publisher 类型之一,它仅发出一个值,然后完成。适用于需要一次性传递单个值的场景。 ```swift import Combine let publisher = Just("Hello Combine") ``` ### 2. `Future` `Future` 用于封装异步操作,例如网络请求或数据库查询。它会在异步操作完成后发出一个值或错误。 ```swift let futurePublisher = Future<String, Never> { promise in // 模拟异步操作 DispatchQueue.global().asyncAfter(deadline: .now() + 1) { promise(.success("Future Result")) } } ``` ### 3. `PassthroughSubject` `PassthroughSubject` 是一种可以手动发送值的 Publisher,适用于需要在代码中主动触发事件的场景。 ```swift import Combine let subject = PassthroughSubject<String, Never>() subject.sink { value in print("Received: $value)") } subject.send("First Value") ``` ### 4. `CurrentValueSubject` `CurrentValueSubject` 类似于 `PassthroughSubject`,但它有一个当前值,并且会立即向新订阅者发送该值。 ```swift let currentValueSubject = CurrentValueSubject<Int, Never>(0) currentValueSubject.sink { value in print("Current value: $value)") } currentValueSubject.send(10) ``` ### 5. `Publishers.Sequence` `Publishers.Sequence` 可以将一个序列(如数组或范围)转换为 Publisher,依次发出序列中的每个元素。 ```swift let sequencePublisher = [1, 2, 3].publisher sequencePublisher.sink { value in print("Sequence value: $value)") } ``` ### 6. `Timer.publish` `Timer.publish` 创建一个基于定时器的 Publisher,定期发出事件。 ```swift let timerPublisher = Timer.publish(every: 1.0, on: .main, in: .default) timerPublisher.sink { _ in print("Timer tick") } timerPublisher.connect() ``` ### 7. `URLSession.DataTaskPublisher` `URLSession.DataTaskPublisher` 是 Combine 框架与网络请求集成的一部分,用于发起网络请求并发出响应数据。 ```swift import Combine let url = URL(string: "https://jsonplaceholder.typicode.com/posts")! let dataTaskPublisher = URLSession.shared.dataTaskPublisher(for: url) dataTaskPublisher.sink { completion in switch completion { case .finished: print("Request finished") case .failure(let error): print("Error: $error.localizedDescription)") } } receiveValue: { data, response in print("Received data: $data.count) bytes") } ``` ### 8. `NotificationCenter.Publisher` `NotificationCenter.Publisher` 允许监听特定的通知,并在通知发出时触发事件。 ```swift import Combine let notificationPublisher = NotificationCenter.default.publisher(for: .UIApplicationWillResignActive) notificationPublisher.sink { _ in print("App will resign active") } ``` ### 9. `Publishers.Map` 和 `Publishers.Filter` 这些是 Combine 框架提供的内置操作符,用于对 Publisher 发出的值进行转换或过滤。 ```swift let numbers = [1, 2, 3, 4, 5].publisher numbers.map { $0 * 2 } .filter { $0 > 5 } .sink { value in print("Filtered and mapped value: $value)") } ``` ### 10. `Publishers.Merge` 和 `Publishers.CombineLatest` `Merge` 和 `CombineLatest` 是用于合并多个 Publisher 的操作符。`Merge` 会将多个 Publisher 发出的值合并为一个流,而 `CombineLatest` 会在所有输入 Publisher 至少发出一个值后,每次其中一个 Publisher 发出新值时,合并最新的值。 ```swift let publisher1 = [1, 2, 3].publisher let publisher2 = [4, 5, 6].publisher publisher1.merge(with: publisher2) .sink { value in print("Merged value: $value)") } let publisherA = PassthroughSubject<Int, Never>() let publisherB = PassthroughSubject<Int, Never>() publisherA.combineLatest(publisherB) .sink { a, b in print("Combine latest: $a), $b)") } publisherA.send(10) publisherB.send(20) ``` ### 11. `Publishers.SwitchToLatest` `SwitchToLatest` 用于处理嵌套的 Publisher 流,当输入 Publisher 发出新的 Publisher 时,它会取消之前的订阅并切换到最新的 Publisher。 ```swift let outerPublisher = PassthroughSubject<PassthroughSubject<String, Never>, Never>() outerPublisher.switchToLatest() .sink { value in print("SwitchToLatest value: $value)") } let innerPublisher1 = PassthroughSubject<String, Never>() let innerPublisher2 = PassthroughSubject<String, Never>() outerPublisher.send(innerPublisher1) innerPublisher1.send("First Value") outerPublisher.send(innerPublisher2) innerPublisher2.send("Second Value") ``` ### 12. `Publishers.Debounce` `Debounce` 用于延迟 Publisher 发出的值,只有在指定的时间间隔内没有新的值发出时,才会最终发出该值。 ```swift let debouncedPublisher = PassthroughSubject<String, Never>() debouncedPublisher.debounce(for: .seconds(1), scheduler: RunLoop.main) .sink { value in print("Debounced value: $value)") } debouncedPublisher.send("A") debouncedPublisher.send("B") debouncedPublisher.send("C") ``` ### 13. `Publishers.Throttle` `Throttle` 用于限制 Publisher 发出值的频率,确保在指定的时间间隔内只发出第一个或最后一个值。 ```swift let throttledPublisher = PassthroughSubject<String, Never>() throttledPublisher.throttle(for: .seconds(1), scheduler: RunLoop.main, latest: true) .sink { value in print("Throttled value: $value)") } throttledPublisher.send("X") throttledPublisher.send("Y") throttledPublisher.send("Z") ``` ### 14. `Publishers.Catch` `Catch` 用于处理 Publisher 发出的错误,并提供一个备用的 Publisher 来继续数据流。 ```swift let failingPublisher = Future<String, Error> { promise in promise(.failure(NSError(domain: "Test", code: -1, userInfo: nil))) } failingPublisher.catch { _ in Just("Fallback Value") }.sink { completion in print("Completion: $completion)") } receiveValue: { value in print("Caught error and received value: $value)") } ``` ### 15. `Publishers.Retry` `Retry` 用于在 Publisher 发出错误时重新订阅它,最多尝试指定的次数。 ```swift var retryCount = 0 let retryPublisher = Future<String, Error> { promise in if retryCount < 2 { retryCount += 1 promise(.failure(NSError(domain: "Retry", code: -1, userInfo: nil))) } else { promise(.success("Success after retry")) } } retryPublisher.retry(2) .sink { completion in print("Retry completion: $completion)") } receiveValue: { value in print("Retry value: $value)") } ``` ### 16. `Publishers.Zip` `Zip` 用于将多个 Publisher 发出的值按顺序配对,并发出组合后的结果。 ```swift let publisherX = [1, 2, 3].publisher let publisherY = ["A", "B", "C"].publisher publisherX.zip(publisherY) .sink { value in print("Zipped value: $value.0), $value.1)") } ``` ### 17. `Publishers.Scan` `Scan` 用于累积 Publisher 发出的值,类似于 `reduce` 操作。 ```swift let scanPublisher = [1, 2, 3, 4].publisher scanPublisher.scan(0) { accumulator, value in accumulator + value }.sink { value in print("Scanned value: $value)") } ``` ### 18. `Publishers.Share` `Share` 用于共享 Publisher 的订阅,避免多次执行相同的异步操作。 ```swift let sharedPublisher = URLSession.shared.dataTaskPublisher(for: URL(string: "https://jsonplaceholder.typicode.com/posts")!) .map { $0.data } .share() sharedPublisher.sink { completion in print("First subscriber completed: $completion)") } receiveValue: { data in print("First subscriber received data: $data.count) bytes") } sharedPublisher.sink { completion in print("Second subscriber completed: $completion)") } receiveValue: { data in print("Second subscriber received data: $data.count) bytes") } ``` ### 19. `Publishers.HandleEvents` `HandleEvents` 用于在 Publisher 的生命周期中插入调试或日志记录逻辑。 ```swift let handledPublisher = [1, 2, 3].publisher handledPublisher.handleEvents(receiveSubscription: { _ in print("Subscription received") }, receiveOutput: { value in print("Output received: $value)") }, receiveCompletion: { completion in print("Completion received: $completion)") }) .sink { _ in print("Sink completed") } receiveValue: { value in print("Final value: $value)") } ``` ### 20. `Publishers.Buffer` `Buffer` 用于将 Publisher 发出的值缓存到一个数组中,直到达到指定的大小或时间间隔。 ```swift let bufferedPublisher = PassthroughSubject<Int, Never>() bufferedPublisher.buffer(size: 3, prefetch: .byRequesting(1), whenFull: .dropOldest) .sink { values in print("Buffered values: $values)") } bufferedPublisher.send(1) bufferedPublisher.send(2) bufferedPublisher.send(3) bufferedPublisher.send(4) ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值