在c++中找到左、右和相等的最长子串
To find the longest substring with equal sum in left and right in C++
我正在解决一个问题,与我有一些问题:
完成函数getEqualSumSubstring,该函数接受一个参数。单个参数是一个字符串
s
,它只包含非零数字。此函数应打印s
的最长连续子串的长度,使子串的长度为2*N位,并且最左边的N位数字之和等于最右边的N位数字之和。如果没有这样的字符串,你的函数应该打印0。
int getEqualSumSubstring(string s) {
int i=0,j=i,foundLength=0;
for(i=0;i<s.length();i++)
{
for(j=i;j<s.length();j++)
{
int temp = j-i;
if(temp%2==0)
{
int leftSum=0,rightSum=0;
string tempString=s.substr(i,temp);
for(int k=0;k<temp/2;k++)
{
leftSum=leftSum+tempString[k]-'0';
rightSum=rightSum+tempString[k+(temp/2)]-'0';
}
if((leftSum==rightSum)&&(leftSum!=0))
if(s.length()>foundLength)
foundLength=s.length();
}
}
}
return(foundLength);
}
问题是这段代码对一些样本有效,而对其他样本无效。因为这是一个考试类型的问题,所以我也没有测试用例。
代码正常运行
int getEqualSumSubstring(string s) {
int i=0,j=i,foundLength=0;
for(i=0;i<s.length();i++)
{
for(j=i;j<s.length();j++)
{
int temp = j-i+1;
if(temp%2==0)
{
int leftSum=0,rightSum=0;
string tempString=s.substr(i,temp);
// printf("%d ",tempString.length());
for(int k=0;k<temp/2;k++)
{
leftSum=leftSum+tempString[k]-48;
rightSum=rightSum+tempString[k+(temp/2)]-48;
}
if((leftSum==rightSum)&&(leftSum!=0))
if(tempString.length()>foundLength)
foundLength=tempString.length();
}
}
}
return(foundLength);
}
temp变量必须为j-i+1。否则,整个字符串是答案的情况将不会被涵盖。此外,我们需要做斯科特建议的更改。
这是我的解决方案,我可以确认工作。上面的那些并没有真正为我工作-它们不知何故给了我编译错误。我在InterviewStreet上得到了同样的问题,想出了一个糟糕的,不完整的解决方案,对9/15的测试用例有效,所以我不得不花更多的时间编码。
的想法是,而不是关心得到左和右和(这是我最初所做的),我将得到所有可能的子字符串的每一半(左和右一半)的给定输入,排序和附加到两个单独的列表,然后看看是否有任何匹配。
为什么?
假设字符串"423"answers"234"有相同的和;如果我对它们进行排序,它们都是"234",因此是匹配的。由于这些数字必须连续且长度相等,因此我不再需要担心必须将它们加起来作为数字并进行检查。
例如,如果输入的是12345678,那么在左边,for循环将返回:
[1, 12123, 1234, 23234, 3, 34)
右边:
[5, 56567, 5678,…]
等等
但是,我只考虑长度至少为2的子字符串。
我将每个子字符串附加到数组列表中,先转换为字符数组,然后再转换回字符串。
那么现在所有这些都完成了,下一步是检查这两个数组列表中是否有相同数字的相同字符串。我只是对照temp_a的第一个字符串检查temp_b的每个字符串,然后对照temp_a的第二个字符串,以此类推。
如果我得到一个匹配(比如,"234"answers"234"),我将这些匹配子字符串的长度设置为我的tempCount (tempCount = 3)。我还有另一个名为'count'的变量来跟踪这些匹配子字符串的最大长度(如果这是第一次出现匹配,那么count = 0被tempCount = 3覆盖,所以count = 3)。
对于带有变量int end的奇/偶字符串长度,这样做的原因是在代码s.length()/2+j行中,输入的长度恰好是11,那么:
s.length() = 11
s.length()/2 = 11/5 = 5.5 = 5
那么在for循环中,s.length()/2 + j,其中j的最大值是s.length()/2,将变成:
5 + 5 = 10
它没有达到我需要达到的s.length()来获得字符串的最后一个索引。
这是因为子字符串函数要求的结束索引值比charAt(i)之类的值大1。
为了演示,输入"47582139875"将生成以下输出:[47, 457, 4578, 24578, 57, 578, 2578, 58, 258, 28] <——左半部分的子字符串[139, 1389, 13789, 135789, 389, 3789, 35789, 789, 5789, 578] <——右半边的子字符串578 <——最长的匹配6 <——'578'的长度x 2
public static int getEqualSumSubtring(String s){
// run through all possible length combinations of the number string on left and right half
// append sorted versions of these into new ArrayList
ArrayList<String> temp_a = new ArrayList<String>();
ArrayList<String> temp_b = new ArrayList<String>();
int end; // s.length()/2 is an integer that rounds down if length is odd, account for this later
for( int i=0; i<=s.length()/2; i++ ){
for( int j=i; j<=s.length()/2; j++ ){
// only account for substrings with a length of 2 or greater
if( j-i > 1 ){
char[] tempArr1 = s.substring(i,j).toCharArray();
Arrays.sort(tempArr1);
String sorted1 = new String(tempArr1);
temp_a.add(sorted1);
//System.out.println(sorted1);
if( s.length() % 2 == 0 )
end = s.length()/2+j;
else // odd length so we need the extra +1 at the end
end = s.length()/2+j+1;
char[] tempArr2 = s.substring(i+s.length()/2, end).toCharArray();
Arrays.sort(tempArr2);
String sorted2 = new String(tempArr2);
temp_b.add(sorted2);
//System.out.println(sorted2);
}
}
}
// For reference
System.out.println(temp_a);
System.out.println(temp_b);
// If the substrings match, it means they have the same sum
// Keep track of longest substring
int tempCount = 0 ;
int count = 0;
String longestSubstring = "";
for( int i=0; i<temp_a.size(); i++){
for( int j=0; j<temp_b.size(); j++ ){
if( temp_a.get(i).equals(temp_b.get(j)) ){
tempCount = temp_a.get(i).length();
if( tempCount > count ){
count = tempCount;
longestSubstring = temp_a.get(i);
}
}
}
}
System.out.println(longestSubstring);
return count*2;
}
这是我对这个问题的解决方案,包括测试。我添加了一个额外的函数,只是因为我觉得它使解决方案比上面的解决方案更容易阅读。
#include <string>
#include <iostream>
using namespace std;
int getMaxLenSumSubstring( string s )
{
int N = 0; // The optimal so far...
int leftSum = 0, rightSum=0, strLen=s.size();
int left, right;
for(int i=0;i<strLen/2+1;i++) {
left=(s[i]-int('0')); right=(s[strLen-i-1]-int('0'));
leftSum+=left; rightSum+=right;
if(leftSum==rightSum) N=i+1;
}
return N*2;
}
int getEqualSumSubstring( string s ) {
int maxLen = 0, substrLen, j=1;
for( int i=0;i<s.length();i++ ) {
for( int j=1; j<s.length()-i; j++ ) {
//cout<<"Substring = "<<s.substr(i,j);
substrLen = getMaxLenSumSubstring(s.substr(i,j));
//cout<<", Len ="<<substrLen;
if(substrLen>maxLen) maxLen=substrLen;
}
}
return maxLen;
}
这是我做的一些测试。基于以上的例子,他们似乎是对的。
int main() {
cout<<endl<<"Test 1 :"<<getEqualSumSubstring(string("123231"))<<endl;
cout<<endl<<"Test 2 :"<<getEqualSumSubstring(string("986561517416921217551395112859219257312"))<<endl;
cout<<endl<<"Test 3:"<<getEqualSumSubstring(string("47582139875"))<<endl;
}
下面的代码不应该使用tempString.length()而不是s.l ong ()
if((leftSum==rightSum)&&(leftSum!=0))
if(s.length()>foundLength)
foundLength=s.length();
Below is my code for the question... Thanks !!
public class IntCompl {
public String getEqualSumSubstring_com(String s)
{
int j;
int num=0;
int sum = 0;
int m=s.length();
//calculate String array Length
for (int i=m;i>1;i--)
{
sum = sum + m;
m=m-1;
}
String [] d = new String[sum];
int k=0;
String ans = "NULL";
//Extract strings
for (int i=0;i<s.length()-1;i++)
{
for (j=s.length();j>=i+1;k++,j--)
{
num = k;
d[k] = s.substring(i,j);
}
k=num+1;
}
//Sort strings in such a way that the longest strings precede...
for (int i=0; i<d.length-1; i++)
{
for (int h=1;h<d.length;h++)
{
if (d[i].length() > d[h].length())
{
String temp;
temp=d[i];
d[i]=d[h];
d[h]=temp;
}
}
}
// Look for the Strings with array size 2*N (length in even number) and such that the
//the sum of left N numbers is = to the sum of right N numbers.
//As the strings are already in decending order, longest string is searched first and break the for loop once the string is found.
for (int x=0;x<d.length;x++)
{
int sum1=0,sum2=0;
if (d[x].length()%2==0 && d[x].length()<49)
{
int n;
n = d[x].length()/2;
for (int y=0;y<n;y++)
{
sum1 = sum1 + d[x].charAt(y)-'0';
}
for (int y=n;y<d[x].length();y++)
{
sum2 = sum2 + d[x].charAt(y)-'0';
}
if (sum1==sum2)
{
ans = d[x];
break;
}
}
}
return ans;
}
}
下面是解决这个问题的完整Java程序。复杂度为O(n^3)这个可以在O(n^2)内解决。对于O(n^2)复杂度解,请参考此链接
import java.util.Scanner;
import static java.lang.System.out;
public class SubStringProblem{
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
out.println("Enter the Digit String:");
String s = sc.nextLine();
int n = (new SubStringProblem()).getEqualSumSubString(s);
out.println("The longest Sum SubString is "+n);
}
public int getEqualSumSubString(String s){
int N;
if(s.length()%2==0)
{
//String is even
N = s.length();
}
else{
//String is odd
N=s.length()-1;
}
boolean flag =false;
int sum1,sum2;
do{
for(int k=0;k<=s.length()-N;k++){
sum1=0;
sum2=0;
for(int i =k,j=k+N-1;i<j;i++,j--)
{
sum1=sum1 + Integer.parseInt(s.substring(i,i+1));
sum2+=Integer.parseInt(s.substring(j,j+1));
}
if(sum1==sum2){
return N;
}
}
N-=2;
flag =true;
}while(N>1);
return -1;
}
}
这两行数字48的理由是什么?
for(int k=0;k<temp/2;k++)
{
leftSum=leftSum+tempString[k]-48;
rightSum=rightSum+tempString[k+(temp/2)]-48;
}
我只是过于好奇,想听听背后的原因,因为我有一个类似的解决方案,但没有48,它仍然有效。然而,我把48加起来,仍然得到了正确的答案。
解决方案很简单。O (n * n)。S -输入字符串。
var longest = 0;
for (var i = 0; i < s.length-1; i++) {
var leftSum = rightSum = 0;
for (var j = i, k = i+1, l = 2; j >=0 && k < s.length; j--, k++, l+=2) {
leftSum += parseInt(s[j]);
rightSum += parseInt(s[k]);
if (leftSum == rightSum && l > longest) {
longest = l;
}
}
}
console.log(longest);
- 空基优化子对象的地址
- 如果我只是不访问queue_front节点的子节点,而是将它们推到队列中呢?还是BFS吗
- 继承期间显示未知行为的子类
- 将结构向量排序为子组
- 通过指向指针数组的指针访问子类的属性
- VS2017,C++包含目录与附加包含目录,子文件夹包含失败-但为什么
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 从父类方法返回子类对象
- 如何在C++中高效地构造随机骰子
- 如何使用tinyxml2从XML加载父实体和子实体
- 求最长递增子序列C++的长度
- 如何从子成员函数修改父公共成员变量
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 最长的回文子串(C++帮助)
- 如何在 C++11 中的类这样的位集中有效地支持"子位串"?
- 串联数组元素c++的子串
- 对于给定的n个数字序列,找到具有最大总和和尽可能低的计算复杂度的子串
- 将密文分成子串(vigenere密码)
- C中相同字符子串的递归算法
- 查找所有最长公共子串