C++ 如何查找以1开头和结尾的所有子字符串?

C++ 如何查找以1开头和结尾的所有子字符串?,c++,algorithm,C++,Algorithm,给您一个0和1组成的字符串,您必须找到字符串中以1开头和结尾的所有子字符串 例如,给定001011010,输出应为六个字符串: 101 1011 1011001 11 11001 1001 显然存在一个O(N^2)解决方案,但我正在寻找一个复杂性为O(N)的解决方案。有可能吗?如果您只需要子字符串的数量,而不需要子字符串本身,那么您可以在对遇到的1的数量进行初始O(n)和之后,通过计算对的数量来实现 显然存在一个O(N^2)解决方案,但我正在寻找一个复杂性为O(N)的解决方案。可能吗 设k为输

给您一个0和1组成的字符串,您必须找到字符串中以1开头和结尾的所有子字符串

例如,给定001011010,输出应为六个字符串:

101
1011
1011001
11
11001
1001

显然存在一个
O(N^2)
解决方案,但我正在寻找一个复杂性为
O(N)
的解决方案。有可能吗?

如果您只需要子字符串的数量,而不需要子字符串本身,那么您可以在对遇到的1的数量进行初始O(n)和之后,通过计算对的数量来实现

显然存在一个
O(N^2)
解决方案,但我正在寻找一个复杂性为
O(N)
的解决方案。可能吗

k
为输入字符串中
1
s的数目。然后有
O(k^2)
这样的子串。枚举它们必须至少花费
O(k^2)
时间。如果
k~N
,则枚举它们必须花费
O(N^2)
时间

获得
O(N)
解决方案的唯一方法是添加
k
O(sqrt(N))
的要求。在对
k
没有限制的一般情况下,不可能有
O(N)
解决方案

实际的
O(k^2)
解决方案很简单:

std::string input = ...;

std::vector<size_t> ones;
ones.reserve(input.size());

// O(N) find the 1s
for (size_t idx = 0; idx < input.size(); ++idx) {
    if (input[idx] == '1') {
        ones.push_back(idx);
    }
}

// O(k^2) walk the indices
for (size_t i = 0; i < ones.size(); ++i) {
    for (size_t j = i+1; j < ones.size(); ++j) {
        std::cout << input.substr(i, j - i + 1) << '\n';
    }
}
std::字符串输入=。。。;
std::矢量的;
保留(input.size());
//O(N)找到1
对于(size_t idx=0;idxstd::cout您可以通过以下步骤在
O(n)
中找到相同的内容:
1.计算1的数量。
2.设1的#为
x
,我们返回
x(x-1)/2

这非常简单地计算1的可能对数。
代码本身可能值得您自己尝试!
编辑:

如果您想返回子字符串本身,必须限制子字符串中的1的数量,以获得某种
O(N)
解决方案(或者真正的
O(x)
,其中
x
是1的#,因为在一般情况下,枚举它们本身不能从
O(N^2)减少)
时间复杂度。

假设
N
是字符串中
1
s的个数(或者至少与之成比例,假设每个字符的
1
的概率恒定是合理的):

如果您需要子字符串本身,那么将有
N(N-1)/2
,它是二次的,因此不可能比二次的复杂;
import java.util.*;

public class DistictSubstrings {

public static void main(String args[]) {
// a hash set

Scanner in = new Scanner(System.in);
System.out.print("Enter The string");
String s = in.nextLine();
int L = s.length();
Set<String> hs = new HashSet<String>();
// add elements to the hash set
for (int i = 0; i < L; ++i) {


  for (int j = 0; j < L-i ; ++j) {
    if(s.charAt(j)=='1'&&s.charAt(j+i)=='1')
    {
    hs.add(s.substring(j, j+i + 1));
    }

 }
}
Iterator it=hs.iterator();
    System.out.println("the string starts and endswith 1");
    System.out.println(hs.size());
while(it.hasNext())
{
System.out.println(it.next()+" ");
}
公共类区分子字符串{ 公共静态void main(字符串参数[]){ //散列集 扫描仪输入=新扫描仪(系统输入); 系统输出打印(“输入字符串”); 字符串s=in.nextLine(); int L=s.长度(); Set hs=新的HashSet(); //将元素添加到哈希集 对于(int i=0;i
String s=“1001010001”;

对于(inti=0;i,以下python代码将帮助您查找以1开头和结尾的所有子字符串

# -*- coding: utf-8 -*-
"""
Created on Tue Sep 26 14:25:14 2017

@author: Veeramani Natarajan
"""
# Python Implementation to find all substrings that start and end with 1

# Function to calculate the count of sub-strings 
def calcCount(mystring):
    cnt=-1
    index=0    
    while(index<len(mystring)):
        if(mystring[index]=='1'):
            cnt += 1
        index += 1
    return cnt


mystring="0010110010";
index=0;
overall_cnt=0

while(index<len(mystring)):
    if(mystring[index]=='1'):
        partcount=calcCount(mystring[index:len(mystring)])
        overall_cnt=overall_cnt+partcount
#        print("index is",index)
#        print("passed string",mystring[index:len(mystring)])
#        print("Count",partcount,"overall",overall_cnt)
    index=index+1
# print the overall sub strings count
print (overall_cnt)   
#-*-编码:utf-8-*-
"""
创建于2017年9月26日星期二14:25:14
@作者:Veeramani Natarajan
"""
#Python实现查找以1开头和结尾的所有子字符串
#函数来计算子字符串的计数
def calcCount(mystring):
cnt=-1
索引=0
而(指数O(n)溶液则完全可以使用DP。
我们采用一个成对数组,其中每对中的第一个元素表示到该索引的子字符串的数量,第二个元素表示从1开始到但不包括该索引的子字符串的数量(因此,如果该索引处的字符为1,第二个元素将不计算子字符串[1,1])
我们只需迭代数组,并像在DP中那样增量构建解决方案,循环结束后,数组最后一个索引中成对的第一个元素中就有了最终值。下面是代码:

int getoneonestrings(const string &str)
{
    int n = str.length();
    if (n == 1)
    {
        return 0;
    }
    vector< pair<int, int> > dp(n, make_pair(0, 0));
    for (int i = 1; i < n; i++)
    {
        if (str[i] == '0')
        {
            dp[i].first = dp[i - 1].first;
        }
        else
        {
            dp[i].first = dp[i - 1].first + dp[i - 1].second +
                (str[i - 1] == '1' ? 1 : 0);
        }
        dp[i].second = dp[i - 1].second + (str[i - 1] == '1' ? 1 : 0);
    }
    return dp[n - 1].first;
}
intgetonestrings(conststring&str)
{
int n=str.length();
如果(n==1)
{
返回0;
}
向量dp(n,make_对(0,0));
对于(int i=1;i
或者您可以只计算1的数量并计算可能的数量(开始索引、结束索引)以通常的方式配对。你在寻找唯一的子字符串吗?否则问题很简单:你需要计算1的数量。假设这个数字是
n
。现在,你可以用多少种方式选择开始和结束?只需计算
nCr
,其中
n
1s
r=2
的数量。我需要它当每个人都回答这个问题时,你说你需要的是子串的数量,而不是字符串本身。当字符串中有
k
1时,子串的数量是
O(k^2)
。这与
O(n^2)不同
。在这里,我有点不同意你的观点;我认为OP
N
是字符串中的个数;我同意为
N
引入
x
是完全令人困惑的。不过,添加我的定义,
int getoneonestrings(const string &str)
{
    int n = str.length();
    if (n == 1)
    {
        return 0;
    }
    vector< pair<int, int> > dp(n, make_pair(0, 0));
    for (int i = 1; i < n; i++)
    {
        if (str[i] == '0')
        {
            dp[i].first = dp[i - 1].first;
        }
        else
        {
            dp[i].first = dp[i - 1].first + dp[i - 1].second +
                (str[i - 1] == '1' ? 1 : 0);
        }
        dp[i].second = dp[i - 1].second + (str[i - 1] == '1' ? 1 : 0);
    }
    return dp[n - 1].first;
}