2012-12-26 40 views
3

我有一個大字符串char myStr =「AAAABBBCCCCCCDDDEFGHHIJJ」。 我將這個字符串傳遞給我的字符串壓縮函數,它應該返回以下格式的字符串myStr =「A4B3C6D3EFGH2IJ2」 此外,新字符串替換應該只發生在相同的傳遞字符串中。一個不能創建一個臨時數組。如何壓縮一個字符串並用C的計數替換重複項?

下面是我的func,我無法找出刪除重複項並用相同字符串中的數字替換。

#include<stdio.h> 
#include<string.h> 


char* StrCompress(char myStr[]) 
{ 
char *s = myStr; 
int len = strlen(myStr); 
char *in = myStr; 
int count =0; 
int i=0; 


while(*(s) != '\0') 
{ 
    if(*(s)==*(s+1)) 
    { 
     count++; 

     if(count == 1) 
     { 
      in = s; 
     } 
     s++; 

    } 
    else 
    { 
     //myStr[count-1]=count; 
     memcpy(in+1,s+1,count); 
     s=in; 
     count =0; 

    } 
    i++; 
} 

return myStr; 



} 

int main(){ 

char myStr[] ="AAAABBBCCCCCEEFGIIJJJKLMNNNNOOO"; 

printf("Compressed String is : %s\n",StrCompress(&myStr)); 

return 0; 

} 
+2

它看起來像你想執行[遊程編碼(RLE)(http://en.wikipedia.org/wiki/Run -length_encoding),但計數+數據元組反轉。那是對的嗎?另外,我們可以假定你的字符串從來沒有數字,因爲它們會完全使用你的算法? – WhozCraig

回答

3

略加修改:

StrCompress(myStr); // not StrCompress(&myStr) 

如果我們假定你是一個性格:

char* StrCompress(char myStr[]) 
{ 
    char *s, *in; 
    for (s = myStr, in = myStr; *s; s++) { 
    int count = 1; 
    in[0] = s[0]; in++; 
    while (s[0] == s[1]) { 
     count++; 
     s++; 
    } 
    if (count > 1) { 
     int len = sprintf(in, "%d", count); 
     in += len; 
    } 
    } 
    in[0] = 0; 
    return myStr; 
} 

此外,與數組名打電話的時候,你不應該使用運營商的地址不能再重複9次以上,那麼你可以用in[0] = '0' + count代替sprintf的東東:

if (count > 1) { 
    in[0] = '0' + count; 
    in++; 
} 
+0

此解決方案的工作原理,但額外的緩衝區創建.. – Spooferman

+0

哎呀,沒有注意到...現在我更喜歡你的答案.. :) – Spooferman

+1

@faezshingeri,更新多位數字版本以刪除緩衝區 – perreal

2
#include<stdio.h> 

char* StrCompress(char myStr[]) 
{ 
    char *s = myStr; 
    char *r, *p; 
    int count, i; 

    while (*s) 
    { 
     /*initially only 1 character of a kind is present*/ 
     count = 1; 

     /*we check whether current character matches the next one*/ 
     while (*s == *(s+1) && *s) 
     { 
      /*if yes,then increase the count due to the match 
      and increment the string pointer to next */ 
      count++; 
      s++; 
     } 

     if (count > 1) /*if more than one character of a kind is present*/ 
     { 
      /*assign the value of count to second occurence of a particular character*/ 
      *(s - count + 2) = count + '0'; 

      /*delete all other occurences except the first one and second one using array shift*/ 
      for (i = 0; i < count - 2; i++) 
      { 
       p = s + 1; 
       r = s; 

       while (*r) 
        *r++ = *p++; 

       s--; 
      } 
     } 
     s++; 
    } 

    return myStr; 
} 

int main() 
{ 
    char myStr[] = "AAAABBBCCCCCCDDDEFGHHIJJ"; 

    printf("Compressed String is : %s\n", StrCompress(myStr)); 

    return 0; 
} 
+0

刪除代碼中的空行,使其更具可讀性 – Kuf

+0

太棒了!!非常感謝。 – Spooferman

0
public static String compress(String str) { 
    StringBuilder result = new StringBuilder(); 
    int i = 0; 
    int count = 0; 
    while(i < str.length() - 1) { 
     count++; 
     if (str.charAt(i) != str.charAt(i + 1)) { 
      result.append(str.charAt(i)).append(count); 
      count = 0; 
     } 
     i++; 
    } 
    result.append(str.charAt(i)).append(count + 1); 
    return result.toString(); 
} 
0
public static void main(String[] args) { 
    // TODO Auto-generated method stub 
    System.out.print("enter the string"); 
    String s=(new Scanner(System.in)).nextLine(); 
    String s2=new String(""); 
    int count=0; 

    for(int i=0;i<s.length();i++) 
    { 
     count=1; 



     s2=s2+(s.charAt(i)); 

     while(i+1<s.length() && s.charAt(i+1)==s.charAt(i) ) 
     { 
      count++; 

      i++; 

     } 

     s2=s2.concat(count+""); 

     } 

     System.out.print(s2); 
    } 

} 
0

下面是萬一有人需要它的另一種實現方式。僅供參考,此方法稱爲遊程編碼

#include <iostream> 

void CompressString (std::string str) 
{ 
    //count will keep track of the number of occurences of any given character 
    unsigned int count = 1; 

    //new string to store the values from the original string 
    std::string str2 = ""; 

    //store the first letter of the string initially 
    char ch = str[0]; 

    //run a loop from the second character of the string since first character if stored in "ch" 
    for (unsigned int i = 1; i < str.length(); i++) 
    { 
     if (str[i] == ch) 
      count++; 
     else 
     { 
      str2 = str2 + ch + std::to_string (count); 
      ch = str[i]; 
      count = 1; 
     } 
    } 

    //for cases like aabbb 
    str2 = str2 + ch + std::to_string (count); 

    //check if after compression, the length of the string reduces or not 
    if (str.length() > str2.length()) 
     std::cout << str2 << std::endl; 
    else 
     std::cout << str << std::endl; 
} 

int main() 
{ 
    std::cout << "Enter a string to compress: "; 
    std::string str; 
    getline (std::cin, str); 

    std::cout << "Compressed string is: "; 
    CompressString (str); 
    return 0; 
} 
0

這是另一個inplace java程序。我們可以用它代替字符串的StringBuilder

public static void main(String[] args) { 

    String a = "aaabbccaaaddj"; 


     for(int i=0;i<a.length();i++){ 
      int c=i+1; 
      int duplicateCharCount=1; 
      while(c<a.length()&&a.charAt(c)==a.charAt(i)){ 
       ++c; 
       ++duplicateCharCount; 
      } 

       a=a.substring(0,i+1)+duplicateCharCount+a.substring(i+duplicateCharCount); 
       i++; 


     } 
     System.out.println(a); 
    } 
0
public class StringCompression { 
    public static String compress(String str) { 
     StringBuilder result = new StringBuilder(); 
     int i; 
     int count = 0; 
     for(i=0; i< str.length() - 1;i++,count++) { 
      if (str.charAt(i) != str.charAt(i + 1)) { 
       result.append(str.charAt(i)).append(count); 
       count = 0; 
      } 
     } 

     result.append(str.charAt(i)).append(count); 
     return result.toString(); 
    } 

    public static void main(String[] args) { 
     String string = "aaassssdddaaaggghhhfgreeeeeeedrrrrr"; 
     String x= compress(string); 
     System.err.println(x); 
    } 
} 
+0

避免代碼只有答案。添加一些關於它如何回答問題的信息,爲什麼問題出現在第一位或什麼地方。 – Fabulous

相關問題