【问题标题】:Java compressing StringsJava 压缩字符串
【发布时间】:2012-05-25 17:26:00
【问题描述】:

我需要创建一个接收字符串并返回字符串的方法。

例如输入:AAABBBBCC

Ex 输出:3A4B2C

嗯,这很尴尬,我在今天的面试中无法做到(我正在申请初级职位),现在,在家里尝试我做了一些静态工作的东西,我的意思是,不使用没有用的循环,但我不知道我是否没有足够的睡眠时间或其他什么,但我无法弄清楚我的 for 循环应该是什么样子。这是代码:

public static String Comprimir(String texto){

    StringBuilder objString = new StringBuilder();

    int count;
    char match;

        count = texto.substring(texto.indexOf(texto.charAt(1)), texto.lastIndexOf(texto.charAt(1))).length()+1;
        match = texto.charAt(1);
        objString.append(count);
        objString.append(match);

    return objString.toString();
}

感谢您的帮助,我正在努力提高我的逻辑能力。

【问题讨论】:

  • ABC 是否“压缩”为1A1B1C 或保持ABC?那么 AABC -> 2ABC 呢?
  • ABC 应该返回 ABC。 AABC 应该返回 2ABC。谢谢!
  • 在输入中,相同的字母表是否总是放在一起。表示可以输入格式为 AAABBBCCCAACDD??
  • 考试未指定。我想用硬(最好)的方式来做:)。
  • 输入的字符串可以包含数字吗?

标签: java string loops compression


【解决方案1】:

在字符串中循环记住你上次看到的内容。每次你看到相同的字母计数。当您看到一个新字母时,将您计数的内容放在输出中,并将新字母设置为您上次看到的内容。

String input = "AAABBBBCC";

int count = 1;

char last = input.charAt(0);

StringBuilder output = new StringBuilder();

for(int i = 1; i < input.length(); i++){
    if(input.charAt(i) == last){
    count++;
    }else{
        if(count > 1){
            output.append(""+count+last);
        }else{
            output.append(last);
        }
    count = 1;
    last = input.charAt(i);
    }
}
if(count > 1){
    output.append(""+count+last);
}else{
    output.append(last);
}
System.out.println(output.toString());

【讨论】:

    【解决方案2】:

    您可以使用以下步骤来做到这一点:

    • 创建一个HashMap
    • 对于每个字符,从哈希图中获取值 - 如果值为null,则输入1 -else,将值替换为 (value+1)
    • 遍历 HashMap 并保持连接 (Value+Key)

    【讨论】:

    • 我认为这行不通 AAABBAAA 会压缩到无法解压缩的 6A2B !!!
    • 确保HashMapLinkedHashMap,因为其他实现会弄乱密钥顺序。
    • 您的解决方案不适用于这样的字符串:“AAABBBCCAA”
    【解决方案3】:
    • 使用StringBuilder(你这样做了)
    • 定义两个变量 - previousCharcounter
    • 从 0 循环到 str.length() - 1
    • 每次获取str.charat(i) 并将其与previousChar 变量中存储的内容进行比较
    • 如果前一个字符相同,则增加一个计数器
    • 如果前一个字符不相同,并且计数器为 1,则递增计数器
    • 如果前一个字符不相同,并且计数器>1,则追加counter + currentChar,重置计数器
    • 比较后,分配当前字符previousChar
    • 覆盖诸如“first char”之类的极端情况

    类似的东西。

    【讨论】:

      【解决方案4】:

      最简单的方法:- 时间复杂度 - O(n)

      public static void main(String[] args) {
          String str = "AAABBBBCC";       //input String
          int length = str.length();      //length of a String
      
          //Created an object of a StringBuilder class        
          StringBuilder sb = new StringBuilder(); 
      
          int count=1;   //counter for counting number of occurances
      
          for(int i=0; i<length; i++){
              //if i reaches at the end then append all and break the loop
              if(i==length-1){         
                  sb.append(str.charAt(i)+""+count);
                  break;
              }
      
              //if two successive chars are equal then increase the counter
              if(str.charAt(i)==str.charAt(i+1)){   
                  count++;
              }
              else{
              //else append character with its count                            
                  sb.append(str.charAt(i)+""+count);
                  count=1;     //reseting the counter to 1
              }
         }
      
          //String representation of a StringBuilder object
          System.out.println(sb.toString());   
      
      }
      

      【讨论】:

      • 非常好的和简单的答案。
      【解决方案5】:

      在 count=... 行中,lastIndexOf 不会关心连续值,只会给出最后一次出现的值。

      例如,在字符串“ABBA”中,子字符串将是整个字符串。

      另外,取子串的长度相当于减去两个索引。

      我真的认为你需要一个循环。 这是一个例子:

      public static String compress(String text) {
          String result = "";
      
          int index = 0;
      
          while (index < text.length()) {
              char c = text.charAt(index);
              int count = count(text, index);
              if (count == 1)
                  result += "" + c;
              else
                  result += "" + count + c;
              index += count;
          }
      
          return result;
      }
      
      public static int count(String text, int index) {
          char c = text.charAt(index);
          int i = 1;
          while (index + i < text.length() && text.charAt(index + i) == c)
              i++;
          return i;
      }
      
      public static void main(String[] args) {
          String test = "AAABBCCC";
          System.out.println(compress(test));
      }
      

      【讨论】:

      • 很好,我要研究你们给我的所有变量。我不想再经历那种尴尬了。
      【解决方案6】:

      请试试这个。这可能有助于打印我们通过控制台以字符串格式传递的字符数。

      import java.util.*;
      
      public class CountCharacterArray {
         private static Scanner inp;
      
      public static void main(String args[]) {
         inp = new Scanner(System.in);
        String  str=inp.nextLine();
         List<Character> arrlist = new ArrayList<Character>();
         for(int i=0; i<str.length();i++){
             arrlist.add(str.charAt(i));
         }
         for(int i=0; i<str.length();i++){
             int freq = Collections.frequency(arrlist, str.charAt(i));
             System.out.println("Frequency of "+ str.charAt(i)+ "  is:   "+freq); 
         }
           }    
      }
      

      【讨论】:

        【解决方案7】:

        Java 不是我的主要语言,几乎从不使用它,但我想试一试:] 甚至不确定您的分配是否需要一个循环,但这是一个正则表达式方法:

         public static String compress_string(String inp) {
              String compressed = "";
              Pattern pattern = Pattern.compile("([\\w])\\1*");
              Matcher matcher = pattern.matcher(inp);
              while(matcher.find()) {
                 String group = matcher.group();
                 if (group.length() > 1) compressed += group.length() + "";
                 compressed += group.charAt(0);
              }
              return compressed;
           }
        

        【讨论】:

          【解决方案8】:

          这只是另一种方式。

          public static String compressor(String raw) {
                  StringBuilder builder = new StringBuilder();
                  int counter = 0;
                  int length = raw.length();
                  int j = 0;
                  while (counter < length) {
                      j = 0;
                      while (counter + j < length && raw.charAt(counter + j) == raw.charAt(counter)) {
                          j++;
                      }
          
                      if (j > 1) {
                          builder.append(j);
                      }
                      builder.append(raw.charAt(counter));
                      counter += j;
                  }
          
                  return builder.toString();
              }
          

          【讨论】:

          • 感谢你的朋友,我希望你有一个美好的一天。你刚起床,你已经帮助了一个人:)
          【解决方案9】:

          如果您正在寻找基本解决方案,可以使用以下内容。使用一个元素遍历字符串,并在找到所有元素出现后,删除该字符。这样就不会干扰下一次搜索。

          public static void main(String[] args) {
              String string = "aaabbbbbaccc";
              int counter;
              String result="";
              int i=0;
              while (i<string.length()){
                  counter=1;
                  for (int j=i+1;j<string.length();j++){ 
                      System.out.println("string length ="+string.length());  
                      if (string.charAt(i) == string.charAt(j)){
                            counter++;
                      }
                }
                result = result+string.charAt(i)+counter; 
                string = string.replaceAll(String.valueOf(string.charAt(i)), ""); 
              }
              System.out.println("result is = "+result);
          }
          

          输出将是 := 结果是 = a4b5c3

          【讨论】:

            【解决方案10】:
            private String Comprimir(String input){
                    String output="";
                    Map<Character,Integer> map=new HashMap<Character,Integer>();
                    for(int i=0;i<input.length();i++){
                        Character character=input.charAt(i);
                        if(map.containsKey(character)){
                            map.put(character, map.get(character)+1);
                        }else
                            map.put(character, 1);
                    }
                    for (Entry<Character, Integer> entry : map.entrySet()) {
                        output+=entry.getValue()+""+entry.getKey().charValue();
                    }
                    return output;
                }
            

            使用多重番石榴的另一种简单方法-

            import java.util.Arrays;
            
            import com.google.common.collect.HashMultiset;
            import com.google.common.collect.Multiset;
            import com.google.common.collect.Multiset.Entry;
            
            public class WordSpit {
                public static void main(String[] args) {
                    String output="";
                    Multiset<String> wordsMultiset = HashMultiset.create();
                    String[] words="AAABBBBCC".split("");
                    wordsMultiset.addAll(Arrays.asList(words));
                    for (Entry<String> string : wordsMultiset.entrySet()) {
                        if(!string.getElement().isEmpty())
                            output+=string.getCount()+""+string.getElement();
                    }
                    System.out.println(output);
                }
            }
            

            【讨论】:

            • 很好的解决方法,我一步步分析。感谢您的宝贵时间!
            • 它不起作用,因为它无法处理字符重复:"AAABBBCCAA" 将是 "5A3B2C" 而不是 "3A3B2C2A"。此外,HashMap 不保留密钥顺序。请改用LinkedHashMap
            【解决方案11】:

            考虑以下解决方案,其中字符串 s1 标识给定字符串 s(for 循环 1)中可用的唯一字符,在第二个 for 循环中构建一个包含唯一字符且重复次数不重复的字符串 s2通过比较字符串 s1 和 s。

            public static void main(String[] args) 
            {
                // TODO Auto-generated method stub
            
                String s = "aaaabbccccdddeee";//given string
                String s1 = ""; // string to identify how many unique letters are available in a string
                String s2=""; //decompressed string will be appended to this string
                int count=0;
                for(int i=0;i<s.length();i++) {
                    if(s1.indexOf(s.charAt(i))<0) {
                        s1 = s1+s.charAt(i);
                    }
                }
                for(int i=0;i<s1.length();i++) {
                    for(int j=0;j<s.length();j++) {
                        if(s1.charAt(i)==s.charAt(j)) {
                            count++;
                        }
                    }
                    s2=s2+s1.charAt(i)+count;
                    count=0;
                }
            
                System.out.println(s2);
            }
            

            【讨论】:

            • :-P 补充说明
            【解决方案12】:

            也许对你有帮助。

            public class StringCompresser
            {
            public static void main(String[] args)
            {
                System.out.println(compress("AAABBBBCC"));
                System.out.println(compress("AAABC"));
                System.out.println(compress("A"));
                System.out.println(compress("ABBDCC"));
                System.out.println(compress("AZXYC"));
            }
            
            static String compress(String str)
            {
                StringBuilder stringBuilder = new StringBuilder();
                char[] charArray = str.toCharArray();
                int count = 1;
                char lastChar = 0;
                char nextChar = 0;
                lastChar = charArray[0];
                for (int i = 1; i < charArray.length; i++)
                {
                    nextChar = charArray[i];
                    if (lastChar == nextChar)
                    {
                        count++;
                    }
                    else
                    {
                        stringBuilder.append(count).append(lastChar);
                        count = 1;
                        lastChar = nextChar;
            
                    }
                }
                stringBuilder.append(count).append(lastChar);
                String compressed = stringBuilder.toString();
            
                return compressed;
            } 
            }
            

            输出:

            3A4B2C
            3A1B1C
            1A
            1A2B1D2C
            1A1Z1X1Y1C
            

            【讨论】:

              【解决方案13】:

              使用 Map 的答案不适用于 aabbbccddabc 这样的情况,因为在这种情况下输出应该是 a2b3c2d2a1b1c1

              在这种情况下,可以使用此实现:

              private String compressString(String input) {
                      String output = "";
                      char[] arr = input.toCharArray();
                      Map<Character, Integer> myMap = new LinkedHashMap<>();
                      for (int i = 0; i < arr.length; i++) {
                          if (i > 0 && arr[i] != arr[i - 1]) {
                              output = output + arr[i - 1] + myMap.get(arr[i - 1]);
                              myMap.put(arr[i - 1], 0);
                          }
                          if (myMap.containsKey(arr[i])) {
                              myMap.put(arr[i], myMap.get(arr[i]) + 1);
                          } else {
                              myMap.put(arr[i], 1);
                          }
                      }
              
                      for (Character c : myMap.keySet()) {
                          if (myMap.get(c) != 0) {
                              output = output + c + myMap.get(c);
                          }
                      }
              
                      return output;
                  }
              

              【讨论】:

                【解决方案14】:

                O(n) 方法

                不需要散列。这个想法是找到第一个 Non-matching 字符。 每个字符的计数将是两个字符索引的差异。

                详细解答:https://stackoverflow.com/a/55898810/7972621

                唯一的问题是我们需要添加一个虚拟字母,以便比较 最后一个字符是可能的。

                private static String compress(String s){
                    StringBuilder result = new StringBuilder();
                    int j = 0;
                    s = s + '#';
                    for(int i=1; i < s.length(); i++){
                        if(s.charAt(i) != s.charAt(j)){
                            result.append(i-j);
                            result.append(s.charAt(j));
                            j = i;
                        }
                    }
                   return result.toString();
                }
                

                【讨论】:

                • 为了处理最后一个字符,您可以在返回字符串之前添加一个特殊情况,请注意我的答案。虽然你的答案是正确的,但你真的不需要 # 和所有,只要有一个简单的计数器并重置它,只要当前和下一个字符发生变化。
                【解决方案15】:

                下面的代码将要求用户输入一个特定的字符来计算出现次数。

                import java.util.Scanner;
                
                class CountingOccurences {
                
                public static void main(String[] args) {
                
                    Scanner inp = new Scanner(System.in);
                
                    String str;
                    char ch;
                    int count=0;
                
                    System.out.println("Enter the string:");
                    str=inp.nextLine();
                    System.out.println("Enter th Char to see the occurence\n");
                    ch=inp.next().charAt(0);
                
                    for(int i=0;i<str.length();i++)
                    {
                                if(str.charAt(i)==ch)
                        {
                            count++;
                                }
                    }
                
                        System.out.println("The Character is Occuring");
                        System.out.println(count+"Times");
                
                
                }
                
                }
                

                【讨论】:

                  【解决方案16】:
                  public static char[] compressionTester( char[] s){
                  
                      if(s == null){
                          throw new IllegalArgumentException();
                      }
                  
                      HashMap<Character, Integer> map = new HashMap<>();
                      for (int i = 0 ; i < s.length ; i++) {
                  
                          if(!map.containsKey(s[i])){
                              map.put(s[i], 1);
                          }
                          else{
                              int value = map.get(s[i]);
                              value++;
                              map.put(s[i],value);
                          }           
                      }               
                      String newer="";
                  
                      for( Character n : map.keySet()){
                  
                          newer = newer + n + map.get(n); 
                      }
                      char[] n = newer.toCharArray();
                  
                      if(s.length > n.length){
                          return n;
                      }
                      else{
                  
                          return s;               
                      }                       
                  }
                  

                  【讨论】:

                    【解决方案17】:
                    package com.tell.datetime;
                    
                    import java.util.Stack;
                    public class StringCompression {
                        public static void main(String[] args) {
                            String input = "abbcccdddd";
                            System.out.println(compressString(input));
                        }
                    
                        public static String compressString(String input) {
                    
                            if (input == null || input.length() == 0)
                                return input;
                            String finalCompressedString = "";
                            String lastElement="";
                            char[] charArray = input.toCharArray();
                            Stack stack = new Stack();
                            int elementCount = 0;
                            for (int i = 0; i < charArray.length; i++) {
                                char currentElement = charArray[i];
                                if (i == 0) {
                                    stack.push((currentElement+""));
                                    continue;
                                } else {
                                    if ((currentElement+"").equalsIgnoreCase((String)stack.peek())) {
                                        stack.push(currentElement + "");
                                        if(i==charArray.length-1)
                                        {
                                            while (!stack.isEmpty()) {
                    
                                                lastElement = (String)stack.pop();
                                                elementCount++;
                                            }
                    
                                            finalCompressedString += lastElement + "" + elementCount;
                                        }else
                                        continue;
                                    }
                    
                                    else {
                                        while (!stack.isEmpty()) {
                    
                                            lastElement = (String)stack.pop();
                                            elementCount++;
                                        }
                    
                                        finalCompressedString += lastElement + "" + elementCount;
                                        elementCount=0;
                                        stack.push(currentElement+"");
                                    }
                    
                                }
                            }
                    
                            if (finalCompressedString.length() >= input.length())
                                return input;
                            else
                                return finalCompressedString;
                        }
                    
                    }
                    

                    【讨论】:

                      【解决方案18】:
                      public class StringCompression {
                          public static void main(String[] args){
                              String s = "aabcccccaaazdaaa";
                      
                              char check = s.charAt(0);
                              int count = 0;
                      
                              for(int i=0; i<s.length(); i++){
                                  if(s.charAt(i) == check) {
                                      count++;
                                      if(i==s.length()-1){
                                      System.out.print(s.charAt(i));
                                      System.out.print(count);
                                   }
                                  } else {
                                      System.out.print(s.charAt(i-1));
                                      System.out.print(count);
                                      check = s.charAt(i);
                                      count = 1;
                                      if(i==s.length()-1){
                                          System.out.print(s.charAt(i));
                                          System.out.print(count);
                                       }
                                  }
                              }
                          }
                      

                      【讨论】:

                      • 请不要只转储代码作为答案,添加关于如何解决问题的描述。
                      • 马克·罗特维尔给了我-1。但答案是有效的。它将打印正确的答案。
                      • 是的,我给了你一个-1,因为你不应该只是转储代码,你应该解释你的解决方案。
                      【解决方案19】:
                       // O(N) loop through entire character array
                       // match current char with next one, if they matches count++
                       // if don't then just append current char and counter value and then reset counter.
                      // special case is the last characters, for that just check if count value is > 0, if it's then append the counter value and the last char
                      
                       private String compress(String str) {
                              char[] c = str.toCharArray();
                              String newStr = "";
                              int count = 1;
                              for (int i = 0; i < c.length - 1; i++) {
                                  int j = i + 1;
                                  if (c[i] == c[j]) {
                                      count++;
                                  } else {
                                      newStr = newStr + c[i] + count;
                                      count = 1;
                                  }
                              }
                      
                              // this is for the last strings...
                              if (count > 0) {
                                  newStr = newStr + c[c.length - 1] + count;
                              }
                      
                              return newStr;
                          }
                      

                      【讨论】:

                      • @Cristian,虽然我的答案是 A3C4,但您可以通过更改 newStr 轻松更改它。它也在 O(N) 时间内解决了这个问题。
                      【解决方案20】:
                      public class StringCompression {
                          public static void main(String... args){
                              String s="aabbcccaa";
                              //a2b2c3a2
                      
                              for(int i=0;i<s.length()-1;i++){
                                  int count=1;
                                  while(i<s.length()-1 && s.charAt(i)==s.charAt(i+1)){
                                      count++;
                                      i++;
                                  }
                                  System.out.print(s.charAt(i));
                                  System.out.print(count);
                              }
                              System.out.println(" ");
                          }
                      }
                      

                      【讨论】:

                      • 这将为 abc 输出 a1b1。
                      【解决方案21】:

                      这是一个leet code问题443。这里的答案大部分使用StringBuilder或者HashMap,实际问题陈述是使用输入char数组并就地修改数组来解决。

                      public int compress(char[] chars) {
                          int startIndex = 0;
                          int lastArrayIndex = 0;
                          if (chars.length == 1) {
                            return 1;
                          }
                          if (chars.length == 0) {
                            return 0;
                          }
                          for (int j = startIndex + 1; j < chars.length; j++) {
                            if (chars[startIndex] != chars[j]) {
                      
                              chars[lastArrayIndex] = chars[startIndex];
                              lastArrayIndex++;
                              if ((j - startIndex) > 1) {
                                for (char c : String.valueOf(j - startIndex).toCharArray()) {
                                  chars[lastArrayIndex] = c;
                                  lastArrayIndex++;
                                }
                              }
                              startIndex = j;
                            }
                            if (j == chars.length - 1) {
                              if (j - startIndex >= 1) {
                                j = chars.length;
                                chars[lastArrayIndex] = chars[startIndex];
                                lastArrayIndex++;
                                for (char c : String.valueOf(j - startIndex).toCharArray()) {
                                  chars[lastArrayIndex] = c;
                                  lastArrayIndex++;
                                }
                              } else {
                                chars[lastArrayIndex] = chars[startIndex];
                                lastArrayIndex++;
                              }
                            }
                          }
                          return lastArrayIndex;
                        }
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2019-10-15
                        • 2021-04-13
                        • 1970-01-01
                        • 1970-01-01
                        • 2016-01-06
                        相关资源
                        最近更新 更多