C++ 如何查找以1开头和结尾的所有子字符串?
给您一个0和1组成的字符串,您必须找到字符串中以1开头和结尾的所有子字符串 例如,给定001011010,输出应为六个字符串: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为输
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;idx std::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)不同
。在这里,我有点不同意你的观点;我认为OPN
是字符串中的个数;我同意为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;
}