2011-12-12 47 views
2

我解決一個問題,與我有一些問題:要找到在左平等的總和,右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); 

} 

的問題是,這個代碼工作的一些樣品,而不是爲別人。由於這是考試類型問題,我也沒有測試用例。

+0

這是作業嗎? –

+2

爲什麼代碼中有'48'?使用'0',它不會對人產生可怕的影響。 – INS

+1

當它不工作,你怎麼知道它不工作? –

回答

3

此代碼的工作

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); 
} 

臨時變量必須是J-i + 1的。否則,整個字符串是答案的情況將不會被覆蓋。另外,我們需要進行Scott提出的更改。

1

不應該將以下代碼使用tempString.length()而不是s.length()

if((leftSum==rightSum)&&(leftSum!=0)) 
    if(s.length()>foundLength) 
     foundLength=s.length(); 
+0

否,因爲s是字符串的一個對象。 (C++) – rmagon

+0

你的函數返回foundLength。 foundLength只分配給兩個地方:它被聲明的地方被初始化爲0,後來被設置爲'foundLength = s.length()'。你寫的函數只會返回s.length()或者0。正如所寫,它永遠不會返回s的任何子串的長度。 –

+0

嘗試輸入「772」。左半部分和右半部分加起來相同的值的最長的子串是「77」。所以最長的子字符串是2個字符長。當i爲0且j爲2時,tempString將爲「77」,leftSum和rightSum將相等並且將爲7.然後,如你所寫,找到lengthL = s.length(),所以找到的長度將變爲3 !錯誤。它應該變成2,即foundLength = tempString.length()。 –

0

這兩條線上的數字48的理由是什麼?

for(int k=0;k<temp/2;k++) 
{ 
    leftSum=leftSum+tempString[k]-48; 
    rightSum=rightSum+tempString[k+(temp/2)]-48; 
} 

我只是過於好奇,想聽聽它背後的原因,因爲我有一個類似的解決方案,但沒有48,它仍然有效。但是,我添加了48個仍然得到了正確的答案。

+0

嗨,對不起48的混淆,它只是'0的ASCII值 – rmagon

1
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; 

      } 
     } 
2

這是我的解決方案,我可以確認作品。上面的那些實際上並不適合我 - 他們以某種方式給我編譯錯誤。我在InterviewStreet上得到了同樣的問題,提出了一個對9/15個測試用例有效的不完整的解決方案,因此我不得不花費更多的時間進行編碼。

這個想法不是關心如何獲得左和右的總和(這也是我最初做的),我會從給定輸入的每一半(左和右半)中得到所有可能的子串,將它們排序並附加到兩個單獨的列表中,然後查看是否有任何匹配。

爲什麼?

表示字符串「423」和「234」具有相同的總和;如果我對它們進行排序,它們都將是「234」並因此匹配。由於這些數字必須是連續的並且長度相等,我不再需要擔心必須將它們添加爲數字並進行檢查。

因此,舉例來說,如果我給12345678,然後在左側,for循環會給我:

[1,12,123,1234,2,23,234,3,34]

在右邊:

[5,56,567,5678,...]

等等。

但是,我只考慮了長度至少爲2的子字符串。

我附加每個這些子字符串,通過轉換排序爲一個字符數組,然後轉換回一個字符串到ArrayLists。

所以,現在所有這些都完成了,下一步是查看這兩個ArrayLists中是否有相同數字的相同字符串。我簡單地檢查每個temp_b的字符串對temp_a的第一個字符串,然後對temp_a的第二個字符串,等等。

如果我得到一個匹配(比如說「234」和「234」),我將這些匹配的子串的長度設置爲我的tempCount(tempCount = 3)。我還有另一個名爲'count'的變量來跟蹤這些匹配子字符串的最大長度(如果這是第一次匹配,則count = 0會被tempCount = 3覆蓋,所以count = 3)。

至於奇數/偶數字符串長度與變量int結尾,原因是因爲在代碼行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)的東西更大的結束索引。

只是爲了演示, 「47582139875」 的輸入將產生以下輸出: [47,457,4578,24578,57,578,2578,58,258,28] < - 從左半 子串[139,1389,13789,135789,3793,789,35789,789,5789,578] < - 來自右半部分的子串-最長匹配的那個-'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; 
} 
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; 

} 
1

下面是此問題的完整Java程序。 複雜性是這可以然而在O解決爲O(n^3) (N^2)。對於爲O(n^2)的複雜性的解決方案是指this link

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; 
} 
} 
0

簡單的解決方案。 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); 
相關問題