C语言 如何使用C压缩字符串并用其计数替换重复项?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14037263/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to compress a string and replace duplicates with its count using C?
提问by Spooferman
I have a large string char myStr="AAAABBBCCCCCCDDDEFGHHIJJ". I shall pass this string to my string compressing function which should return me the string in below format myStr ="A4B3C6D3EFGH2IJ2" Also, the new string replacements should happen in the same passed string only. One cannot create a temp array.
我有一个大字符串 char myStr="AAAABBBCCCCCCDDDEFGHHIJJ"。我将把这个字符串传递给我的字符串压缩函数,它应该以下面的格式返回我的字符串 myStr ="A4B3C6D3EFGH2IJ2" 此外,新的字符串替换应该只发生在同一个传递的字符串中。不能创建临时数组。
Below is my func and am not able to figure out the deletion of duplicates and replacing with its count in the same string.
下面是我的 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) != '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;
}
')
{
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;
}
采纳答案by perreal
A slightly modified version:
稍微修改的版本:
StrCompress(myStr); // not StrCompress(&myStr)
Additionally, you should not use the address of operator when calling with an array name:
此外,在使用数组名称进行调用时,不应使用运算符的地址:
if (count > 1) {
in[0] = '0' + count;
in++;
}
If you are assuming that a character can't repeat more then 9 times, then you can use in[0] = '0' + countinstead of the sprintfstuff:
如果您假设一个字符不能重复超过 9 次,那么您可以使用in[0] = '0' + count代替sprintf内容:
#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 == *(s+1))
{
/*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;
}
回答by abhay jain
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();
}
回答by Pani Dhakshnamurthy
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);
}
}
回答by nishant
#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;
}
回答by Testing123
Below is another implementation in case anyone needs it. FYI, this method is called run-length encoding
下面是另一种实现,以防有人需要它。仅供参考,这种方法称为游程编码
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);
}
回答by M Sach
Here is another inplace java program . We can use StringBuilder instead of string
这是另一个就地 java 程序。我们可以使用 StringBuilder 而不是 string
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);
}
}
回答by jeetpal
#include<stdio.h>
#include<conio.h>
char* compress(char* str);
int main(){
clrscr();
char str[1000];
scanf("%[^\n]s", str);
char* s = compress(str);
printf("\n%s", s);
getch();
return 0;
}
char* compress(char* str){
char* s = str;
int count = 1;
char str2[1000] = " // aaeezaa : a4e2z1
function compressString(str) {
const obj = {};
const sortedArr = [...str].sort();
for(i = 0; i<sortedArr.length; i++) {
let c = 1;
while((sortedArr[i] === sortedArr[i+1]) && sortedArr[i+1]) {
c++;
i++;
}
obj[sortedArr[i]] = c;
}
return Object.keys(obj).reduce((compressedStr, k) => compressedStr + k + obj[k], '');
}
";
char* n = str2;
while(*(s) != ' #include <stdio.h>
#include <string.h>
char *compress(char *input) {
int i = 0;
int count = 1;
int k = 0;
int j = 0;
int len = 0;
int digits_in_count = 0;
char count_str[3];
int m = 0;
for(i = 0; i < strlen(input); i++) {
j = i+1;
m = 0;
count = 1;
len = strlen(input);
printf("\niteration: %d, string = %s",i, input);
while((input[j] != '##代码##') && (input[j] == input[i])) {
count++;
j++;
}
sprintf(count_str, "%d", count);
digits_in_count = strlen(count_str);
//this means we have reaced last alphabet in the string
if(input[j] == '##代码##' && count == 1) {
k = k+1;
goto count_append;
}
input[k++] = input[i];
// we are assuming that we have enough space in the end, to move string.
// we are memmove for remaining portion of the string.
// if the string is "aaab", then we have to move 'b' one step ahead
// and it will look like "aab", later in the end we are adding count,
// and making it as "a3b".
// if the string is "ab", then we have to move 'b' one step away,
// to make space for adding 'count'.
// and the new string after memmove will looklike "abb",
// in the end we are adding count and making it as "a1b"
// memmove will not hit for last character in the string, because there
// is already enough space for appending 'count'.
memmove((input+i+digits_in_count+1) , input+j, len-j+1);
i = i+digits_in_count;
count_append:
{
while(digits_in_count) {
input[k++] = *(count_str+m);
m = m+1;
digits_in_count--;
}
}
}
return input;
}
void main()
{
char arr[50] = "aaab";
printf("\n%s\n", compress(arr));
}
'){
if(count == 1){
*n = *s;
n++;
}
if(*(s) == *(s+1)){
count++;
s++;
}
else{
*n = '0' + count;
n++;
count = 1;
s++;
}
}
return str2;
}
回答by Alok Kumar
回答by Isha Mahajan
Here's another solution with ES6:
这是 ES6 的另一个解决方案:
##代码##回答by Ellanti Kishore
I made two assumptions and wrote this code,
我做了两个假设并写了这段代码,
we have space double the size of string which we are encoding. i.e., suppose we are encoding "ab", then the space space allotted should be at-least 4 bytes.
continuous streak of alphabets can be max 999. if there is a chance that there can be 1000 same characters in adjacent positions then, we have to increase "count_str" char array size accordingly.
我们有两倍于我们正在编码的字符串大小的空间。即,假设我们正在编码“ab”,那么分配的空间空间应该至少为 4 个字节。
字母的连续条纹最多可以是 999。如果相邻位置有可能有 1000 个相同的字符,那么我们必须相应地增加“count_str”字符数组的大小。

