首页 > 试题广场 >

字符串压缩算法

[编程题]字符串压缩算法
  • 热度指数:5931 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 32M,其他语言64M
  • 算法知识视频讲解
输入一串字符,请编写一个字符串压缩程序,将字符串中连续出现的重复字母进行压缩,并输出压缩后的字符串。
例如:
aac 压缩为 1ac
xxxxyyyyyyzbbb 压缩为 3x5yz2b



输入描述:
任意长度字符串


输出描述:
压缩后的字符串
示例1

输入

xxxxyyyyyyzbbb

输出

3x5yz2b
按从前往后的顺序直接压缩
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String str;
        while((str = br.readLine()) != null) {
            char[] chars = str.toCharArray();
            int step = 0;
            int count = 1;
            char flag = chars[step];
            StringBuilder sb = new StringBuilder();
            while(step < chars.length - 1){
                step ++;
                if(chars[step] != flag){
                    // 关键字改变,进行压缩
                    if(count > 1)
                        sb.append(count - 1).append(flag);
                    else
                        sb.append(flag);
                    // 修改关键字,将计数置1
                    count = 1;
                    flag = chars[step];
                }else{
                    // 关键字不变,直接计数+1
                    count ++;
                }
            }
            // 最后一个关键字需要单独处理
            if(count > 1)
                sb.append(count - 1).append(flag);
            else
                sb.append(flag);
            System.out.println(sb.toString());
        }
    }
}


发表于 2020-11-27 17:39:20 回复(0)
/*
思路二:不断寻找每次字符重复的情况,然后将它导入到StringBuffer中
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main{
    public static void main(String[] args) throws IOException{
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        String str = br.readLine();
        StringBuffer sb = new StringBuffer();
        for(int i = 0,eindex = 0;i<str.length();){
            char ch = str.charAt(i);
            int count = 0;
            while(eindex < str.length() && ch==str.charAt(eindex)){
                count++;
                eindex++;
            }
            if(count==1)
                sb.append(ch);
            else
                sb.append(count - 1).append(ch);
            i = eindex;
        }
        System.out.println(sb.toString());
        
    }
}

发表于 2020-05-22 15:10:10 回复(0)
a,m,p,q = input() + ' ','','',0
for i in range(len(a)):
    if p != a[i]:
        m += (str(q) if q else '') + p
        p,q = a[i],0
    else:
        q += 1
print(m)

发表于 2020-03-22 13:56:08 回复(0)
JS实现的
let str = "xxxyzxxyzzzxxsxy";
let obj = {};
for (var i =0; i < str.length; i++) {
    let temp = str.charAt(i);
    let reg = "/"+temp+"/g";
    let result = str.replace(eval(reg),"");
    obj[temp] = str.length-result.length;
}
let results = "";
for (let item in obj) {
    if(obj[item] == 1) {
        results += "";
    }else{
        results += obj[item];
    }
    results += item;
}
console.log(results);
发表于 2019-10-22 17:00:22 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main(){
    string s;
    getline(cin,s);
    int l = s.length(), t=1;
    char c = s[0];
    for(int i=1;i<l;i++){
        if(s[i]==c){
            t++;
        }else{
            if(t>1)
                cout<<t-1;
            cout<<c;
            c = s[i];
            t = 1;
        }
    }
    if(t>1)
        cout<<t-1;
    cout<<c<<endl;
    return 0;
}

发表于 2019-10-09 08:43:17 回复(0)
    // 字符串压缩算法
    // https://www.nowcoder.com/practice/2ff3d36b4d4a4bfeb1a7d64f3cc55c15
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String s = sc.nextLine();
        StringBuilder ret = new StringBuilder();
        Stack<Character> stack = new Stack<Character>();
        for (int i = 0; i < s.length(); i++) {
            if (stack.isEmpty() || stack.peek() == s.charAt(i)) {
                stack.push(s.charAt(i));
            } else {
                int size = stack.size();
                if (size > 1) {
                    ret.append(size - 1);
                }
                ret.append(stack.peek());
                stack.clear();
                stack.push(s.charAt(i));
            }
        }
        int size = stack.size();
        if (size > 1) {
            ret.append(size - 1);
        }
        ret.append(stack.peek());
        stack.clear();
        System.out.println(ret.toString());
    }

使用栈来记录重复的字符,思路上好理解一点,当栈为空的时候或者栈不为空并且当前制度等于栈顶字符的时候,则入栈,否则则出栈,同时记录栈的大小进行拼接字符串
发表于 2019-08-24 14:33:37 回复(0)
import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringBuilder sb = new StringBuilder(br.readLine());
        sb.append('#');
        StringBuilder res = new StringBuilder();
        int count = 1;
        for (int i = 0; i < sb.length() - 1; i++) {
            if (sb.charAt(i) == sb.charAt(i + 1)) {
                count++;
            } else {
                if (count > 1) {
                    res.append(count - 1);
                }
                res.append(sb.charAt(i));
                count = 1;
            }
        }
        System.out.println(res.toString());
    }
}
编辑于 2019-08-20 17:21:31 回复(0)
s = input()
res,i = '',0
while(i<len(s)):
    temp = i
    while(i+1<len(s) and s[i]==s[i+1]):
        i+=1
    res += str(i-temp)+s[i] if i-temp>0 else s[i]
    i+=1
print(res)

发表于 2019-08-12 10:45:25 回复(0)
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<cstdio>
 
using namespace std;
int main()
{
    string str,final_str;
    int sum;
    while(getline(cin,str)) //cin>>str会忽略输入的空格导致错误,getline保留空格
    {
        size_t len=str.size();
        for(int i=0;i<len;)
        {
            sum=0;
            for(int j=i;j<len;j++)
            {
                sum+=str[i]==str[j];
                if(str[i]!=str[j])
                    break;
            }
            if(sum>1)
                final_str+=to_string(sum-1)+str[i];
            else
                final_str+=str[i];
            i=i+sum;
        }
    }
    cout<<final_str;
}

发表于 2019-05-08 16:51:41 回复(0)
#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    getline(cin,s);
    int n=0;
    for(int i=1;i<s.size();i++)
    {
        if(s[i-1]==s[i])
            n++;
        else
        {
            if(n>0)
                cout<<n<<s[i-1];
            else
                cout<<s[i-1];
            n=0;
        }
    }
    if(n>0)
        cout<<n<<s[s.size()-1];
    else
        cout<<s[s.size()-1];
    return 0;
}

发表于 2019-08-16 22:25:41 回复(0)
#include <bits/stdc++.h>
using namespace std;

int main()
{
    string str;
    getline(cin, str);
    for(int i = 0; i < str.length(); i++)   //遍历字符串
    {
        int cnt = 0;   //用来记录重复字符数量
        while(str[i] == str[i+1])   //判断是不是字符串中的重复字符
        {
            i++;
            cnt++;
        }
        if(cnt != 0)
        {
            cout << cnt;   //先输出压缩的字符个数
        }
        cout << str[i];   //再输出被压缩的字符
    }
    return 0;
}

发表于 2019-06-28 23:22:48 回复(0)
public class Main {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("输入字符串:");
        String s1 =sc.nextLine();
        char[] s2= s1.toCharArray(); //把取到的字符串变成一个char数组
        StringBuffer stringBuilder1=new StringBuffer();
        int count =0;
        char c = s1.charAt(0) ;//初始化,之后c值变化
        for (int i = 1; i < s1.length(); i++) {
            if(s2[i] == c){
                count++;
                if(i==s1.length()-1){
                    stringBuilder1.append(count);
                }
                //c=s2[i];
            }else {//这块是一个断点,说明下个元素和上面的不同,进而判断前面那段是重复段还是单数,进行一一输出
                if (count>0) {
                    //上一段元素重复计数>1,则可以输出count和c
                    stringBuilder1.append(count);
                    stringBuilder1.append(c);
                    count=0;
                }else{//不是>1的话就是前面那段是单元素,那么count置1,开始比较元素变成当前值
//                    这里解释count=0情况
                    stringBuilder1.append(c);
                }//else2
/*    
            输入字符串:
0123456
输入字符串:
sddweww
7
s1dwew
*/
            }//else1
            //最后两个元素是双数时,那么count++之后,因为没有后续元素,那么直接跳到,c=s2[i]之后便跳出循环了
            
            c=s2[i];//此时最后一个元素才被赋值为c
        }//for
        stringBuilder1.append(c);
        System.out.println(stringBuilder1);
    }
}

发表于 2019-05-27 16:48:57 回复(0)
package main

import (
    "fmt"
    "strconv"
    "os"
    "bufio"
)

var in=bufio.NewReader(os.Stdin)

func main() {
    s,_:=in.ReadString('\n')
    s=s[:len(s)-1]
    ans:=""
    var pre byte
    cnt:=0
    for i,ch:=range []byte(s){
        if i==0{
            pre=ch
            continue
        }
        if ch==pre{
            cnt++
        }else{
            if cnt==0{
                ans+=string(pre)
            }else{
                ans+=strconv.Itoa(cnt)+string(pre)
            }
            pre=ch
            cnt=0
        }
    }
    if cnt==0{
        ans+=string(pre)
    }else{
        ans+=strconv.Itoa(cnt)+string(pre)
    }
    fmt.Print(ans)
}

发表于 2023-03-18 17:48:26 回复(0)
import java.util.Scanner;
public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String str = sc.nextLine();
        char[] ch = str.toCharArray();
        for(int i = 0;i < ch.length;i++){
            int count = 0;
            while(i < ch.length - 1 && ch[i] == ch[i+1]){
                count++;
                i++;
            }
            if(count != 0){
                System.out.print(count);
            }
            System.out.print(ch[i]);
        }
            System.out.println();
    }
}

发表于 2022-04-14 16:58:11 回复(0)
#include<iostream>
#include<sstream>
using namespace std;

void zipp(string str,string &str1)
{
    int n=str.size();
    int j=0;
    for(int i=0;i<n;i++)
    {
        if(str[i]==str[i+1])
            {
                j++;
            }
        else
        {
            string p;
            stringstream ss;
            ss<<j;
            ss>>p;
            if(j>0)
                str1+=p;
            str1+=str[i];
            j=0;
        }
    }
    return;


int main()
{
    string str,str1;
    str1="";
    getline(cin,str);
    zipp(str,str1);
    cout<<str1;
}
发表于 2021-10-21 15:03:28 回复(0)
#include<stdio.h>

char* stringpress(char* input);
char* stringpress(char* input)
{
    char *out=input;
    int i=0,j=0,n=0;
    for(i=0;i<=strlen(input);++i){
        if(input[i]==input[i+1]){
            n+=1;
        }
        else{
            if(n==0){
                out[j]=input[i];
                j+=1;
            }
            else{
                out[j]='0'+n;
                out[j+1]=input[i];
                j+=2;
            }
            n=0;
        }
    }
    char *res=(char*)malloc(sizeof(char)*j);
    strncpy(res,out,j);
    return res;
}
int main(void)
{
    char inputstring[1000];
    char* input;
    char* output;
    gets(inputstring);
    input=inputstring;
    output=stringpress(input);
    printf("%s",output);
    free(output);
    return 0;
}

发表于 2021-08-31 16:09:28 回复(0)
之前用的是while(cin>>str){..... str+=' '} 结果和使用getline一样,但只能80%,不知道为什么
#include <iostream>
using namespace std;
int main()
{
    string str;
    string res;
    getline(cin, str);
        char num='0';
    for(int i=0;i<str.size();i++)
    {
 
        if(i+1<str.size()&&str[i+1]==str[i]) num++;
        else
        {
            if(num>='1') res+=num;
            res+=str[i];
            num='0';
        }
    }
        res+=' ';
     
    cout<<res<<endl;
    return 0;
}


发表于 2020-12-17 20:24:47 回复(0)
while(line = readline()) {
    let input = line;
    let outArr = [];
    let count = 0;
    for (let i = 0; i < input.length; i++) {
        if (input[i] === input[i + 1]) {
            count ++;
        } else {
            if(count !== 0){
                outArr.push(count);
            };
            outArr.push(input[i]);
            count = 0;
        };
    };
    console.log(outArr.join(''));
};

发表于 2020-06-20 15:42:29 回复(0)
function getZipStr(str) {
    let newStr = "";
    let count = 1;
    for(let i = 0; i < str.length; i ++){
        let curStr = str.charAt(i);
        let j = i + 1;
        let nextStr = str.charAt(j);
        if(curStr == nextStr) {
            count ++;
            j ++;
        }else {
            if(count == 1){
                newStr += curStr;
            }
            if(count > 1) {
                count --;
                newStr += count + curStr;
                j --;
                count = 1;
            }
        }
    }
    return newStr;
}
自测完全没问题,不知道怎么牛客不给过==!  请大佬指教
发表于 2020-06-10 10:38:25 回复(2)
a = input()
a = a + ";"
c = 0
b = ""
for i in range(len(a)-1):
    if a[i] == a[i+1]:
        c = c + 1
        continue
    if c == 0:
        b = b + a[i]
    else:
        b = b + str(c) + a[i]
    c = 0
print(b)

发表于 2020-05-01 17:20:51 回复(0)